Python中的元类
作者:互联网
# 在Python中基于类可以创建对象
class Foo:
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
# 根据类创建对象
obj = Foo('Miracle') # 创建这个obj对象 先经过 __new__ 创建对象,然后经过__init__初始化对象
print(obj) # -> <__main__.Foo object at 0x0000017497088880>
对象是基于类创建出来的。那么类是由谁创建的? 类默认是由type创建的。
# 通过type创建一个类
# 参数:类名、继承谁、成员(类属性、和方法)
Boo = type('Coo', (object,), {'name': 'miracle', "func": lambda self: 666})
print(Boo()) # -> <__main__.Coo object at 0x000001796D9AE610>
类默认由type创建,怎么让一个类创建的方式改成其他东西呢?使用元类
# Foo类由MyType创建
# Foo是一个对象,由MyType创建,那么他就一定会执行MyType中的__new__方法和__init__方法
class MyType(type):
def __init__(cls, name, bases, attrs):
"""
当__new__构造方法执行完之后就会执行该初始化方法
当class Foo 声明metaclass=MyType时就会调用__init__
:param name: 类名称 Foo
:param bases: 继承谁 ()
:param attrs: 类里面的成员(属性、方法)
{'__module__': '__main__', '__qualname__': 'Foo',
'__init__': <function Foo.__init__ at 0x000001F8235AB310>,
'__new__': <function Foo.__new__ at 0x000001F8236B8700>,
'__call__': <function Foo.__call__ at 0x000001F8236B80D0>,
'__classcell__': <cell at 0x000001F8235A8E50: MyType object at 0x000001F8236E2400>}
"""
super().__init__(name, bases, attrs)
def __new__(mcs, *args, **kwargs):
"""
当class Foo 声明metaclass=MyType时就会调用__new__
mcs等于MyType这个类(也就是元类)
通过调用它父类type中的__new__方法来创建Foo这个类,然后返回出去
:param args:
这个参数就是用type创建类是需要传递的参数
('Foo', (), {'__module__': '__main__', '__qualname__': 'Foo'})
:param kwargs:
"""
new_cls = super().__new__(mcs, *args, **kwargs)
print(new_cls) # -> <class '__main__.Foo'>
return new_cls
def __call__(cls, *args, **kwargs):
"""
call方法是在对象加()是被触发,在这里Foo()就是MyType的对象 那么Foo()就会触发到这里的call
:param args:
这里参数接收的就是Foo()括号中的位置参数
:param kwargs:
这里参数接收的就是Foo()括号中的关键词参数
:return:
"""
# 调用自己那个类的__new__方法也就是Foo的__new__方法来创建对象
empty_object = cls.__new__(cls, *args, **kwargs)
# 调用自己那个类的__init__方法也就是Foo的__init__方法来初始化对象
cls.__init__(empty_object, *args, **kwargs)
# 返回这个对象也就是返回Foo()这个对象
return empty_object
class Foo(metaclass=MyType):
def __init__(self):
print('Foo init')
def __new__(cls, *args, **kwargs):
return super(Foo, cls).__new__(cls)
def __call__(self, *args, **kwargs):
# 这里的call在Foo()这个对象 加()后触发
# 也就是f=Foo() f()时候触发这里的call
print('Foo——————call')
标签:__,Python,元类,init,kwargs,new,Foo,cls 来源: https://www.cnblogs.com/miracleeeeeeee/p/16061728.html