Adi*_*iva 6 python oop inheritance
作为 OOP 的新手,我想知道是否有任何方法可以根据子类在 Python 中的调用方式继承多个类之一。我尝试这样做的原因是因为我有多个同名的方法,但在三个具有不同功能的父类中。在创建对象时,必须根据某些条件继承相应的类。
例如,我试图根据实例化时是否传递任何参数来使C类继承A或B,但没有成功。谁能建议更好的方法来做到这一点?
class A:
def __init__(self,a):
self.num = a
def print_output(self):
print('Class A is the parent class, the number is 7',self.num)
class B:
def __init__(self):
self.digits=[]
def print_output(self):
print('Class B is the parent class, no number given')
class C(A if kwargs else B):
def __init__(self,**kwargs):
if kwargs:
super().__init__(kwargs['a'])
else:
super().__init__()
temp1 = C(a=7)
temp2 = C()
temp1.print_output()
temp2.print_output()
Run Code Online (Sandbox Code Playgroud)
所需的输出将是“A 类是父类,编号是 7”,后跟“B 类是父类,没有给出编号”。
谢谢!
无论您是刚刚开始接触 OOP 还是已经使用了一段时间,我都建议您阅读一本关于设计模式的好书。Gamma 的《设计模式》是一个经典之作。舵。约翰逊和弗利赛德斯。
您可以使用带有委托的组合,而不是使用继承。例如:
class A:
def do_something(self):
# some implementation
class B:
def do_something(self):
# some implementation
class C:
def __init__(self, use_A):
# assign an instance of A or B depending on whether argument use_A is True
self.instance = A() if use_A else B()
def do_something(self):
# delegate to A or B instance:
self.instance.do_something()
Run Code Online (Sandbox Code Playgroud)
更新
为了回应 Lev Barenboim 的评论,下面演示了如何使带有委托的组合看起来更像常规继承,以便如果类C已经分配了类的实例A,例如 to ,则诸如之类self.instance的属性可以也可以在内部访问(假设类本身没有定义属性),同样,如果您创建name的实例,则可以像class继承自 class一样引用它。Axself.xself.instance.xCxCcattributec.xCA
这样做的基础在于内置方法__getattr__和__getattribute__。__getattr__可以在类上定义,并且每当引用但未定义属性时都会调用。__getattribute__可以在对象上调用以按名称检索属性。
请注意,在下面的示例中,如果类所做的只是委托给 ,那么它C甚至不再需要定义方法:do_somethingself.instance
class A:
def do_something(self):
# some implementation
class B:
def do_something(self):
# some implementation
class C:
def __init__(self, use_A):
# assign an instance of A or B depending on whether argument use_A is True
self.instance = A() if use_A else B()
def do_something(self):
# delegate to A or B instance:
self.instance.do_something()
Run Code Online (Sandbox Code Playgroud)
印刷:
class A:
def __init__(self, x):
self.x = x
def do_something(self):
print('I am A')
class B:
def __init__(self, x):
self.x = x
def do_something(self):
print('I am B')
class C:
def __init__(self, use_A, x):
# assign an instance of A or B depending on whether argument use_A is True
self.instance = A(x) if use_A else B(x)
# called when an attribute is not found:
def __getattr__(self, name):
# assume it is implemented by self.instance
return self.instance.__getattribute__(name)
# something unique to class C:
def foo(self):
print ('foo called: x =', self.x)
c = C(True, 7)
print(c.x)
c.foo()
c.do_something()
# This will throw an Exception:
print(c.y)
Run Code Online (Sandbox Code Playgroud)