测试环境Python 3.7.1
参考链接
两句话轻松掌握 Python 最难知识点——元类
Python进阶:一步步理解Python中的元类metaclass
什么是元类?
1 __new__()方法和__init__()方法的区别
1.1 __new__()方法需要有返回值,__init__()不需要返回值
实质区别是new()需要返回父类或者说超类的new()后的结果,init()返回一个None,不需要手动return
__new__()方法需要有返回值
2 __new__()方法在类和元类中用法的区别
2.1 在类中使用__new__()方法
这里说的类的普通类
class Single(object):
_instance = None
def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance
def __init__(self):
pass
single1 = Single()
single2 = Single()
print(id(single1) == id(single2))
class Spider:
i = 0
def __new__(cls, *args, **kwargs):
print('cls.i > ', cls.i)
cls.i += 1
return super().__new__(cls, *args, **kwargs)
def __init__(self):
print('self.i > ', self.i)
Spider()
Spider()
Spider()
输出如下
True
cls.i > 0
self.i > 1
cls.i > 1
self.i > 2
cls.i > 2
self.i > 3
在普通类中使用new的第一个参数是cls,而init的第一个参数是self
- cls 表示当前类
- self 表示当前实例
2.2 在元类中使用__new__()方法
元类有如下定义方式
class ChattyType(type):
def __new__(cls, name, bases, dct):
print("Allocating memory for class", name)
return type.__new__(cls, name, bases, dct)
def __init__(cls, name, bases, dct):
print("Init'ing (configuring) class", name)
super(ChattyType, cls).__init__(name, bases, dct)
print(type(ChattyType))
ins=ChattyType("duck", (object, ), dict())
print(type(ins))
输出如下
<class 'type'>
Allocating memory for class duck
Init'ing (configuring) class duck
<class '__main__.ChattyType'>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。