簡體   English   中英

Python:如何調用具有多重繼承的多個super __new__?

[英]Python: how to call multiple super __new__ with multiple inheritance?

我有2類: AB ,兩者通過實例化__new__具有不同組的參數(像aA ,和foo, barB )。 現在,我想實現從AB繼承的類C ,並使用3個args實例化它: a, foo, bar ,將對應的參數傳遞給超類__new__ ,但是這里出了問題。

如果沒有參數,我只調用super(C, cls).__new__()和類C對象成功創建(它同時調用A.__new__()B.__new__()並以某種方式進行組合)。 但是,如何“手動”操作呢? 所以,我想通過aA.__new__foo, barB.__new__並結合莫名其妙地返回實例(是獲得類的對象這個正確的方式C在結束了嗎?)。

無論如何我都不能做到。

拳頭-調用A.__new__會在o = super(A, cls).__new__(cls)引發不正確的參數數量異常o = super(A, cls).__new__(cls)A.__new__() o = super(A, cls).__new__(cls) A.__new__() (但是A可以實例化為獨立的)

第二-我不知道如何將成功實例化的類AB對象組合到類C對象中。

所以可以請人解釋一下這里發生了什么嗎?

class A(object):
    def __new__(cls, a):
        o = super(A, cls).__new__(cls)
        setattr(o, 'a', a)
        return o

class B(object):
    def __new__(cls, foo, bar):
        o = super(B, cls).__new__(cls)
        setattr(o, 'foo', foo)
        setattr(o, 'bar', bar)
        return o

print A(1) # ok, <__main__.A object at 0x00000000022F1630>
print B(2,3) # ok, <__main__.B object at 0x00000000022F1630>


class C(A,B):
    def __new__(cls, a, foo, bar):
        o1 = A.__new__(cls, a) #fail - exception while calling super.new in A
        o2 = B.__new__(cls, foo, bar)  #fail - exception while calling super.new in A
        # return # What? How to combine o1 o2 even if they are created succesfuly?
        # # return super(C, cls).__new__(cls, ?????)

print C(1,2,3)

方法__new__是創建您的實例的對象,您不應多次調用super(...).__new__ ,因為它將創建多個實例。

您想使用__init__來初始化已創建的實例。

class A(object):
    def __init__(self, a):
        self.a = a

class B(object):
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

class C(A, B):
    def __init__(self, a, foo, bar):
        A.__init__(self, a)
        B.__init__(self, foo, bar)

特別要指出的是,在多重繼承中,Python會同時調用A.__new__B.__new__並“以某種方式組合”是不正確的。 看一下這段代碼

class A(object):
    def __new__(*args):
        print('A.__new__ was called')
        return type(*args) # This is what ultimately creates every object in Python

class B(object):
    def __new__(*args):
        print('B.__new__ was called')
        return type(*args)

# As expected the following is printed when instances are created
a = A() # Prints 'A.__new__ was called'
b = B() # Prints 'B.__new__ was called'

class C(A, B):
    pass

c = C() # Prints 'A.__new__ was called'

因此,我們觀察到從未調用過B.__new__ 在多重繼承時,Python將從具有該方法的最左邊的類繼承該方法 在這種情況下, C繼承了A.__new__

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM