_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")
_
_parent.py
_でmethodb()
を呼び出す方法はありますか?
これを行うことは、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()
これはもちろんこれを返します:
lol, it works
実際には、親からの呼び出しはなく、子クラスのインスタンスからの関数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
確かに、parent.py
内から新しいB
オブジェクトを作成することはできませんが、何らかの方法でparent.py
の関数に渡された場合は、そのメソッドを引き続き使用できます。 。
これを行うには3つの方法があります。ただし、構成/デカップリングには設計パターンの点で特定の利点があるため、アプローチ#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()