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

Jag*_*N M 16 python inheritance class parent

parent.py:

class A(object):
    def methodA(self):
        print("in methodA")
Run Code Online (Sandbox Code Playgroud)

child.py

from parent import A
class B(A):
    def methodb(self):
        print("am in methodb")
Run Code Online (Sandbox Code Playgroud)

反正是有打电话methodb()parent.py

dan*_*ano 24

这样做只有在A是抽象基类时才有意义,这意味着它A只是用作其他类的基础,而不是直接实例化.如果是这种情况,您将methodB在A类上定义,但保持未实现:

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")
Run Code Online (Sandbox Code Playgroud)

这不是绝对必要的.如果你没有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")
Run Code Online (Sandbox Code Playgroud)

使用它实际上会阻止您实例化A或继承的任何类A而不覆盖methodB.例如,如果B看起来像这样:

class B(A):
   pass
Run Code Online (Sandbox Code Playgroud)

尝试实例化它时会出错:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class B with abstract methods methodB
Run Code Online (Sandbox Code Playgroud)

如果您尝试实例化,也会发生同样的情况A.

  • 为什么要显式设置`__metaclass__`,而不只是在定义中使用ABC 作为基类? (3认同)
  • @naught101当我写这个答案时,我认为使用 `__metaclass__` 是唯一的方法(并且仍然是 Python 2.x 上的唯一方法)。我同意,如果你现在使用 Python 3,使用“ABC”作为基类是正确的方法。我已经相应地更新了我的答案。 (2认同)

Ale*_*xey 8

你可以这样做:

class A():
    def foo(self):
        self.testb()

class B(A):
    def testb(self):
        print('lol, it works')
b = B()
b.foo()
Run Code Online (Sandbox Code Playgroud)

注意,实际上没有来自父级的调用,只是foo从子类的实例调用函数,这个实例继承foo自父类,即这是不可能的:

lol, it works
Run Code Online (Sandbox Code Playgroud)

将产生: AttributeError: A instance has no attribute 'testb'

因为

a=A()
a.foo()
Run Code Online (Sandbox Code Playgroud)

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


The*_*nse 1

您可以在任何地方使用该函数,只要它附加到一个对象(它似乎来自您的示例)。如果您有一个B对象,那么您绝对可以在任何地方使用它的methodb()功能。

parent.py:

class A(object):
    def methoda(self):
        print("in methoda")

def aFoo(obj):
  obj.methodb()
Run Code Online (Sandbox Code Playgroud)

child.py

from parent import A
class B(A):
    def methodb(self):
        print("am in methodb")
Run Code Online (Sandbox Code Playgroud)

导入后您可以看到它是如何工作的:

>>> from parent import aFoo
>>> from child import B
>>> obj = B()
>>> aFoo(obj)
am in methodb
Run Code Online (Sandbox Code Playgroud)

当然,您将无法B从内部创建新对象parent.py,但如果它以某种方式传递给函数,您仍然可以使用它的方法parent.py