对象在定义 __new__ 后不带参数
object takes no parameters after defining __new__
在 python 3.3 及更高版本中,当我们覆盖 __new__()
时,我们不必将参数和关键字参数传递给 super().__new__()
或 object.__new__()
。但是这个调用super().__new__()
returns一个class的实例。
那么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__,因此解释器可以检查是否 instance 是 cls.
的实例
初始化器(__init__)被分配器(__new__)自动调用为[Python.Docs]: object.__new__(cls[, ...]) 状态(重点 是我的):
If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...])
, where self is the new instance and the remaining arguments are the same as were passed to __new__().
If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked.
code00.py:
#!/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 {0:s} on {0:s}\n".format(sys.version, sys.platform))
main()
输出:
e:\Work\Dev\Whosebug\q054511671>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code00.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\Whosebug\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.Docs]: Data model), but rather to [Python]: New-style Classes
有关更多详细信息,您还可以检查检查[Python 2.2.Docs]: Overriding the __new__ method(Singleton class)。
这里重要的是初始调用,比如 spam = Spam('x', 1)
。
在内部,Python 调用 __new__
作为 class 方法 class Spam
使用传递的参数 . Spam.__new__
实际做什么并不重要,它只是应该 return 一个对象。
它确实使用 object.__new__
构建了一个 Spam
对象。由于创建的对象具有正确的 class,Python 使用初始参数 .
对其 调用 __init__
在 python 3.3 及更高版本中,当我们覆盖 __new__()
时,我们不必将参数和关键字参数传递给 super().__new__()
或 object.__new__()
。但是这个调用super().__new__()
returns一个class的实例。
那么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__,因此解释器可以检查是否 instance 是 cls.
的实例初始化器(__init__)被分配器(__new__)自动调用为[Python.Docs]: object.__new__(cls[, ...]) 状态(重点 是我的):
If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like
__init__(self[, ...])
, where self is the new instance and the remaining arguments are the same as were passed to __new__().If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked.
code00.py:
#!/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 {0:s} on {0:s}\n".format(sys.version, sys.platform))
main()
输出:
e:\Work\Dev\Whosebug\q054511671>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code00.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\Whosebug\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.Docs]: Data model), but rather to [Python]: New-style Classes 有关更多详细信息,您还可以检查检查[Python 2.2.Docs]: Overriding the __new__ method(Singleton class)。
这里重要的是初始调用,比如 spam = Spam('x', 1)
。
在内部,Python 调用 __new__
作为 class 方法 class Spam
使用传递的参数 . Spam.__new__
实际做什么并不重要,它只是应该 return 一个对象。
它确实使用 object.__new__
构建了一个 Spam
对象。由于创建的对象具有正确的 class,Python 使用初始参数 .
__init__