[英]Python: how to call multiple super __new__ with multiple inheritance?
我有2類: A
和B
,兩者通過實例化__new__
具有不同組的參數(像a
為A
,和foo, bar
為B
)。 現在,我想實現從A
和B
繼承的類C
,並使用3個args實例化它: a, foo, bar
,將對應的參數傳遞給超類__new__
,但是這里出了問題。
如果沒有參數,我只調用super(C, cls).__new__()
和類C
對象成功創建(它同時調用A.__new__()
和B.__new__()
並以某種方式進行組合)。 但是,如何“手動”操作呢? 所以,我想通過a
到A.__new__
, foo, bar
到B.__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
可以實例化為獨立的)
第二-我不知道如何將成功實例化的類A
和B
對象組合到類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.