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")
Est-il possible d'appeler methodb()
dans parent.py
?
Cela n'aurait de sens que si A
est une classe de base abstraite, ce qui signifie que A
est uniquement destiné à être utilisé comme base pour d'autres classes, et non instancié directement. Si tel était le cas, vous définiriez methodB
sur la classe A, mais vous ne le laisseriez pas implémenté:
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")
Ce n'est pas strictement nécessaire. Si vous ne déclarez pas methodB
nulle part dans A
et instanciez B
, vous pourrez toujours appeler methodB
à partir du corps de methodA
, mais c'est une mauvaise pratique; on ne sait pas d'où methodA
est supposé provenir, ni que les classes enfant doivent la remplacer.
Si vous voulez être plus formel, vous pouvez utiliser le module Python abc
pour déclarer A en tant que classe de base abstraite.
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")
En l'utilisant, cela vous empêchera effectivement d'instancier A
ou de toute classe héritant de A
sans remplacer methodB
. Par exemple, si B ressemblait à ceci:
class B(A):
pass
Vous obtiendrez une erreur en essayant de l'instancier:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class B with abstract methods methodB
La même chose se produirait si vous essayiez d’instancier A
.
Vous pouvez faire quelque chose comme ça:
class A():
def foo(self):
self.testb()
class B(A):
def testb(self):
print 'lol, it works'
b = B()
b.foo()
Notez qu’en réalité, il n’ya pas d’appel de parent, il n’ya qu’appel de fonction foo
depuis une instance de classe enfant, cette instance a hérité de foo
depuis parent, c’est-à-dire que c’est impossible:
a=A()
a.foo()
produira: AttributeError: A instance has no attribute 'testb'
parce que
>>> dir(A)
['__doc__', '__module__', 'foo']
>>> dir(B)
['__doc__', '__module__', 'foo', 'testb']
Ce que je voulais montrer, c’est que vous pouvez créer une instance de classe enfant, qui contiendra toutes les méthodes et tous les paramètres du parent et de ses propres classes.
Vous pouvez utiliser la fonction n'importe où tant qu'elle est attachée à un objet , ce qui semble provenir de votre exemple. Si vous avez un objet B
, vous pouvez alors utiliser sa fonction methodb()
de manière absolue.
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")
Vous pouvez voir comment cela fonctionne après l'importation:
>>> from parent import aFoo
>>> from child import B
>>> obj = B()
>>> aFoo(obj)
am in methodb
Certes, vous ne pourrez pas créer un nouvel objet B
à partir de parent.py
, mais vous pourrez quand même utiliser ses méthodes si elles sont transmises à une fonction dans parent.py
d'une manière ou d'une autre.
Il y a trois approches/façons de faire cela! mais je recommande fortement d'utiliser l'approche n ° 3 car la composition/découplage présente certains avantages en termes de modèle de conception. ( 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()