python - 定义 __new__ 后对象不带任何参数

标签 python python-3.x python-internals

在 python 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__,因此解释器可以检查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\StackOverflow\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\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.Docs]: Data model ),而是特定于 [Python]: New-style Classes 更多详情,您还可以查看[Python 2.2.Docs]: Overriding the __new__ method (Singleton 类)。

关于python - 定义 __new__ 后对象不带任何参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54511671/

相关文章:

python - 如何使用 Python 和 patoolib 解压 .rar 文件

python - 在python中生成固定长度的随机字符串列表

python - 如何读取文本文件并转换为字典?

python - 有没有办法判断 python 是否使用 "--with-threads --enable-shared"配置和编译?

Python:为什么右移>>向下舍入,应该在哪里使用?

python - 为什么字典在删除后不调整大小?

Python 3 整数地址

python - 列表python的内存大小

python - pandas - 列间条件的最佳行选择

python - 为 Python 包添加虚拟命名空间