我还发现一个问题就是,我们一般的的类都是self必写。而__new__写的是cls,他们有什么不同。
查了一波资料,cla主要用于类定义方法,而self则是实例方法。
个人理解,当运行到这个方法的时候,类如果还没实例化,就是cls,否则是self。
接着下面给一个例子
class ClsTest:
def __init__(self):
print('init')
print(self)
@classmethod
def whoAmI(cls):
print('cls')
print(cls)
test = ClsTest()
test.whoAmI()
print(test.__class__)
返回值为
init
<__main__.ClsTest object at 0x7f18431ac0f0>
cls
<class '__main__.ClsTest'>
<class '__main__.ClsTest'>
先讨论下结果
很显然cls和test.__class__的返回值是一样的,说明他只是类而self已经是实例化的对象了。
那么他们决定了什么?
class Foo:
def __new__(cls):
print('__new__')
print(cls)
print(super().__new__(cls))
return super().__new__(cls)
def __init__(self):
print('__init__')
print(self)
foo = Foo()
print(foo)
执行结果
__new__
<class '__main__.Foo'>
<__main__.Foo object at 0x03F137B0>
__init__
<__main__.Foo object at 0x03F137B0>
<__main__.Foo object at 0x03F137B0>
从例子可以看出
先执行__new__方法,再执行__init__方法。实例化是在__new__中完成的,进入__init__时,self已经实例化了。
在上例中,cls和self只是个名字,貌似(我测试的是这样)写什么都可以,他需要在那个位置,用这样一个名字只是为了区别,当前的对象是什么。如果对象在metaclass中我们用mcs。
静态方法和类方法
class Foo:
def foo1(self):
print(self)
@staticmethod
def foo2():
print("foo2")
@classmethod
def foo3(cls):
print(cls)
f = Foo()
f.foo1()
f.foo2()
f.foo3()
返回结果
<__main__.Foo object at 0x05AE3830>
foo2
<class '__main__.Foo'>
这里也是一组调用,Foo中有常规调用,静态方法和类方法。类方法要传cls返回是一个class实例,静态方法不能传self。
我们也可以从这里看到他们的不同。