对象限定__new__后没有参数

问题描述 投票:1回答:2

在蟒蛇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

可有人请什么发生在这里解释一下吗?

python python-3.x python-internals
2个回答
1
投票

您通过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(单例类)。


1
投票

这里的问题是最初的电话,说spam = Spam('x', 1)

在内部,Python会自动调用__new__作为类Spam与传递的参数类方法。什么Spam.__new__实际上做的是不是真的很重要,它只是应该返回一个对象。

它使用object.__new__建立一个Spam对象。由于创建的对象具有正确的类,Python会自动调用__init__它与最初的参数。

© www.soinside.com 2019 - 2024. All rights reserved.