__new__关于实例化的混淆

时间:2018-03-13 07:53:27

标签: python instantiation

我试图了解__new__如何运作,目前我无法弄明白。

根据this blog post explaining the __new__ method,要构建我的实例,我会这样做:super(MyClass, cls).__new__(cls, *args, **kwargs)

但是,每当我指示我的__new__从另一个类实例化时,它似乎没有接受参数,或者如果我Bar.__new__(cls)它似乎根本不接受这个。完全糊涂了。

我的代码:

class Bar(object):
    def __init__(self,a,b,c):
       self.a = a
       self.b = b
       self.c = c

    def hello(self):
        print("HelloBar")

class Foo(object):
    def __new__(cls, *args, **kwargs):
        return Bar.__new__(cls) # Have tried doing stuff like 
                                # super().__new__(bar) as well, no success

    def __init__(self, a, b):
        self.a = a
        self.b = b

i = Foo(2,3,4)

我试图指向班级Bar的一个实例,我该怎么做?

1 个答案:

答案 0 :(得分:4)

直接致电Bar(); Bar()完全是一个不同的类,Foo.__new__不必处理该类的实现方式。

如果您希望能够创建Foo(...)个实例, 必须传递您Bar()调用的参数:

class Foo(object):
    def __new__(cls, *args, **kwargs):
        return Bar(*args, **kwargs)

您只需在super().__new__()内使用Foo.__new__,因为您已覆盖object.__new__方法但仍需要访问它以创建实际实例。

您仍然可以致电Bar.__new__(Bar, *args, **kwargs)object.__new__(Bar, *args, **kwargs),但之后您将绕过Bar.__init__方法。那是因为ClassObject(...)被翻译为type(ClassObject).__call__(ClassObject, ...),然后__call__()方法的工作就是调用__new__,然后只有__init__ __new__生成了ClassObject的实例。用Python代码表示,看起来有点像这样:

def __call__(type_, cls, *args, **kwargs):
    instance = cls.__new__(cls, *args, **kwargs)
    if isinstance(instance, cls):
        instance.__init__(*args, **kwargs)
    return instance

如果Foo.__new__()返回Bar的实例,则isinstance(instace, Foo)为false,而type(Foo).__call__()实现不会在该对象上调用__init__方法。通过致电Bar(),您确保type(Bar).__call__()已经负责调用Bar.__init__()