parent.py
:
class A(object):
def methodA(self):
print("in methodA")
child.py
:
from parent import A
class B(A):
def methodb(self):
print("am in methodb")
无论如何在methodb()
打电话给parent.py
?
如果A
是一个抽象基类,这样做才有意义,这意味着A
只是用作其他类的基础,而不是直接实例化。如果是这种情况,您可以在A类上定义methodB
,但保持未实现:
class A(object):
def methodA(self):
print("in methodA")
def methodB(self):
raise NotImplementedError("Must override methodB")
from parent import A
class B(A):
def methodB(self):
print("am in methodB")
这不是绝对必要的。如果你没有在methodB
中任何地方声明A
,并实例化B
,你仍然可以从methodB
的身体调用methodA
,但这是一个不好的做法;目前还不清楚methodA
应该来自哪里,或者儿童类需要覆盖它。
如果您想要更正式,可以使用Python abc
模块将A声明为抽象基类。
from abc import ABCMeta, abstractmethod
class A(object):
__metaclass__ = ABCMeta
def methodA(self):
print("in methodA")
@abstractmethod
def methodB(self):
raise NotImplementedError("Must override methodB")
使用它实际上会阻止你实例化A
或任何继承A
的类而不覆盖methodB
。例如,如果B看起来像这样:
class B(A):
pass
尝试实例化它时会出错:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class B with abstract methods methodB
如果您尝试实例化A
,也会发生同样的情况。
你可以这样做:
class A():
def foo(self):
self.testb()
class B(A):
def testb(self):
print 'lol, it works'
b = B()
b.foo()
注意,实际上没有来自父级的调用,只是从子类的实例调用函数foo
,这个实例从父类继承了foo
,即这是不可能的:
a=A()
a.foo()
将产生:AttributeError: A instance has no attribute 'testb'
因为
>>> dir(A)
['__doc__', '__module__', 'foo']
>>> dir(B)
['__doc__', '__module__', 'foo', 'testb']
我想表明你可以创建子类的实例,它将拥有父类和它自己的类的所有方法和参数。
您可以在任何地方使用该功能,只要它附加到一个对象,它似乎来自您的样本。如果你有一个B
对象,那么你可以在任何地方使用它的methodb()
函数。
parent.py:
class A(object):
def methoda(self):
print("in methoda")
def aFoo(obj):
obj.methodb()
child.py
from parent import A
class B(A):
def methodb(self):
print("am in methodb")
导入后,您可以看到它的工作原理:
>>> from parent import aFoo
>>> from child import B
>>> obj = B()
>>> aFoo(obj)
am in methodb
当然,你将无法从B
中创建一个新的parent.py
对象,但是如果它以某种方式传递给parent.py
中的函数,你仍然可以使用它的方法。
有三种方法/方法可以做到这一点!但我强烈建议使用方法#3,因为组合/解耦在设计模式方面具有一定的好处。 (GOF)
## approach 1 inheritance
class A():
def methodA(self):
print("in methodA")
def call_mehtodB(self):
self.methodb()
class B(A):
def methodb(self):
print("am in methodb")
b=B()
b.call_mehtodB()
## approach 2 using abstract method still class highly coupled
from abc import ABC, abstractmethod
class A(ABC):
def methodA(self):
print("in methodA")
@abstractmethod
def methodb(self):
pass
class B(A):
def methodb(self):
print("am in methodb")
b=B()
b.methodb()
#approach 3 the recommended way ! Composition
class A():
def __init__(self, message):
self.message=message
def methodA(self):
print(self.message)
class B():
def __init__(self,messageB, messageA):
self.message=messageB
self.a=A(messageA)
def methodb(self):
print(self.message)
def methodA(self):
print(self.a.message)
b=B("am in methodb", "am in methodA")
b.methodb()
b.methodA()