python元类

  • Post author:
  • Post category:python


在python中可以基于类创建对象

# 定义类
class Foo(object):
	def __init(self, name):
		self.name = name
	def __new__(cls, *args, **kwargs):
		return object.__new__(cls)

obj = Foo("lucky") # lucky

#根据类创建对象时程序内部的实际步骤

  1. 执行类的new方法,创建空对象 【构造方法】
  2. 执行类的init方法,初始化对象 【初始化方法】

可以看出对象是由类创建的,那么类是由谁创建的呢?

答:类默认是由type创建的
# 传统方法创建类
class Foo(object):
	v1 = 123
	def func(self):
		return 666

# 非传统方式创建类(一行)
# 创建类型 类名 继承类 成员
Fa = type("Foo", (object,),{"v1":123,"func":lambda self:666})

# 根据类创建对象
obj = Fa()
# 调用v1的变量(类变量)
print(obj.v1) # 123
# 执行对象中的func方法
result = obj.func() # 666

可以看出type是可以创建类的,那怎么让一个类的创建改成其他的东西呢?

这个时候就引出了

元类



元类

: 创建类的类

# type 创建Foo类
class Foo(object):
	pass
# 其他东西创建Foo类
class Foo(object, metaclass=其他东西):
	pass

那么现在我们就可以创建一个类继承type,再创建另一个类继承前一个类

class MyType(type):
	pass

class Foo(object, metaclass=MyType):
	pass
# Foo类由MyType创建

这时候其实可以把

Foo

假设成一个由

MyType

创建的对象,那我们在创建

Foo

类时也就是在执行

MyType

类中的

new



init

方法

接下来我们可以在

MyType

类中写一些方法验证一下调用关系和执行顺序

class MyType(type):
	def __init__(self, *args, **kargs):
		print('init')
		super().__init__(cls, *args, **kwargs)
		
	def __new__(cls, *args, **kwargs):
		print('new')
		new_cls = super().__new__(cls, *args, **kwargs)
		return new_cls
		
	def __call__(self, *args, **kwargs):
		 # 调⽤⾃⼰的那个类 __new__ ⽅法去创建对象
		 empty_object = self.__new__(self)
		 # 调⽤你⾃⼰的__init__ ⽅法去初始化
		 self.__init__(empty_object, *args, **kwargs)
		 return empty_object

class Foo(object, metaclass=MyType):
	def __init__(self, name):
 		self.name = name

# 假设Foo是⼀个对象 由MyType创建
# Foo其实是MyType的⼀个对象
# Foo() -> MyType对象()
# 对象+()实际执行就是继承类的__call__方法

v1 = Foo("lucky") # 等价于MyTpe.__call__ 结果为 new init
print(v1.name) # lucky

在学习元类之后,我们可以在

  • 类创建时自定义功能(

    __new__

    ,

    __init__

    )
  • 对象创建前后自定义功能(

    __call__

拓展(元类实现单例模式):

class MyType(type):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.instance = None

    def __call__(self, *args, **kwargs):
        # 判断是否有对象,有则不创建,没有则创建
        if not self.instance:
            self.instance = self.__new__(self)
        # 初始化
        self.__init__(self.instance, *args, **kwargs)
        return self.instance


class Singleton(object, metaclass=MyType):
    pass


class Foo1(Singleton):
    pass


v1 = Foo1()
v2 = Foo1()
print(v1)
print(v2)



版权声明:本文为python147原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。