从python中的父类文件调用子类方法

问题描述 投票:12回答:4

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

python class inheritance parent
4个回答
21
投票

如果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,也会发生同样的情况。


6
投票

你可以这样做:

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']

我想表明你可以创建子类的实例,它将拥有父类和它自己的类的所有方法和参数。


2
投票

您可以在任何地方使用该功能,只要它附加到一个对象,它似乎来自您的样本。如果你有一个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中的函数,你仍然可以使用它的方法。


0
投票

有三种方法/方法可以做到这一点!但我强烈建议使用方法#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()
© www.soinside.com 2019 - 2024. All rights reserved.