web-dev-qa-db-fra.com

appel de la méthode de classe enfant à partir du fichier de classe parent en python

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?

10
Jagadeesh N M

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.

20
dano

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.

6
Alexey

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.

2
TheSoundDefense

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()
0
grepit