在蟒蛇3.3及更高版本,当我们覆盖__new__()
,我们没有传递参数和关键字参数super().__new__()
或object.__new__()
。但这种呼吁super().__new__()
返回一个类的实例。
Python是怎样传递的参数其余__init__
呢?
class Spam(object):
''' Hello I am Spam '''
def __new__(cls, *args, **kwargs):
print("Creating Instance")
instance = object.__new__(cls) # Who passed *args and **kwargs to __init__?
print(instance)
return instance
def __init__(self, a, b):
print("Init Called")
self.a = a
self.b = b
可有人请什么发生在这里解释一下吗?
您通过CLS作为参数传递给object.__new__
,所以解释可以检查实例是否是CLS的一个实例。
初始化(__init__)由分配器(__new__)自动调用作为[Python 3]: object.__new__(cls[, ...])(重点是矿)规定:
如果__new__()返回CLS的一个实例,则新实例的__init__()方法将被调用像
__init__(self[, ...])
,其中self是新实例,其余参数是为传递给__new__()相同。如果__new__()不返回CLS的实例,那么新实例的__init__()方法将不会被调用。
code.朋友:
#!/usr/bin/env python3
import sys
class Spam(object):
''' Hello I am Spam '''
def __new__(cls, *args, **kwargs):
print("Creating Instance")
instance = object.__new__(cls) # Who passed *args and **kwargs to __init__?
print(instance)
#return instance # If you return anything else (1, object(), or None by commenting the line) here, __init__ won't be called
if len(sys.argv) == 1: # DO NOT DO THIS!!! It's just for demo purposes
return instance
def __init__(self, a, b):
print("Init Called")
self.a = a
self.b = b
def main():
spam = Spam(1, 2)
print(type(spam), dir(spam))
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
输出:
e:\Work\Dev\StackOverflow\q054511671>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32 Creating Instance <__main__.Spam object at 0x000001F8E24D14E0> Init Called <class '__main__.Spam'> ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b'] e:\Work\Dev\StackOverflow\q054511671>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py arg Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32 Creating Instance <__main__.Spam object at 0x0000020808F71550> <class 'NoneType'> ['__bool__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
请注意,这不是具体到Python 3(检查[Python 2]: Data model),而是[Python]: New-style Classes欲了解更多详情,您还可以检查检查[Python 2.2]: Overriding the __new__ method(单例类)。
这里的问题是最初的电话,说spam = Spam('x', 1)
。
在内部,Python会自动调用__new__
作为类Spam
与传递的参数类方法。什么Spam.__new__
实际上做的是不是真的很重要,它只是应该返回一个对象。
它使用object.__new__
建立一个Spam
对象。由于创建的对象具有正确的类,Python会自动调用__init__
它与最初的参数。