[英]How to set and get a parent class attribute from an inherited class in Python?
[英]Get attribute of parent of parent of a multilevel inherited class
讓我們想象一下下面的類結構:
class A:
def t(self):
print("a")
class B(A):
def t(self):
super().t()
print("b")
我想從繼承自B
的類C
,使用super
關鍵字僅運行At()
方法,以便運行
c=C()
c.t()
僅打印
a
作為信息,讓我們假設我確實希望C
像B
一樣工作,但方法t()
除外 ,該方法必須完全繞過Bt()
才能覆蓋At()
。
我試過了
class C(B):
def t(self):
super().super().t()
返回AttributeError: 'super' object has no attribute 'super'
。
我也試過
class C(B):
def t(self):
A.t()
它返回TypeError: t() missing 1 required positional argument: 'self'
。
顯然,我做錯了。 有人可以告訴我如何繼承第二個父級的方法,同時仍繼承第一個父級的方法嗎?
您可以重新設計類層次結構,以使B
和C
都繼承自A
的公共子類,該子類實現了當前B
類所實現的每個方法,除了方法t
之外,方法t
留給了新的B
類自己實現:
class A:
def t(self):
print("a")
class SubA(A):
def other_method(self):
pass
class B(SubA):
def t(self):
super().t()
print("b")
class C(SubA):
pass
正如我在評論中提到的那樣,您可以使用At(self)
實現目標。
但是..似乎沒有必要這樣做。
class A:
def real_t(self):
print("a")
def t(self):
self.real_t()
class B(A):
def t(self):
self.real_t()
print("b")
class C(B):
def t(self):
self.real_t()
print("c")
這是殘酷的,您永遠都不要這樣做,但是有可能。
請記住, super()
是super(__class__, self_or_whatever_the_first_argument_is)
,但是將MRO中的任何類作為第一個參數傳遞是合法的。
即使替換了全局變量(例如,用imp.reload
),以下代碼也將起作用,但是如果其他內容從B
繼承並在MRO中進入C和B之間,則下面的代碼將imp.reload
。 如果您用硬編碼B代替next_class
,那么您將跳過此類,並且如果替換全局變量,它將中斷。
#!/usr/bin/env python3
class A:
def t(self):
print("a")
class B(A):
def t(self):
super().t()
print("b")
class C(B):
def t(self):
s = super()
# s.__self_class__ == self.__class__ == type(self) == F
mro = s.__self_class__.mro()
# unless globals are replaced, s.__thisclass__ == __class__ == C
thisclass_index = mro.index(__class__)
next_class = mro[thisclass_index+1]
# unless globals are replaced or something else inherits from B, next_class == B
super(next_class, self).t()
print('c')
class D(A):
def t(self):
super().t()
print('d')
class E(A):
def t(self):
super().t()
print('e')
class F(D, C, E):
def t(self):
super().t()
print('f')
def main():
assert F.mro() == [F, D, C, B, E, A, object]
print('This should print the letters `aecdf` in order:')
F().t()
if __name__ == '__main__':
main()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.