Python 类继承:将方法放在何处?

Python 类继承:将方法放在何处?,python,oop,Python,Oop,例如,我们有一个名为a的基类和三个名为B C D的子类,都是a的继承。如果我想要某个方法只出现在B和C中,而不出现在D中。我应该把这个方法放在哪里 如果我把它放在A中,D将有它不需要的方法 如果我把它放在B和C中,我重复我自己的话。如果它是B和C中可见的“相同”方法,听起来你需要在A下面的层次结构中添加另一个类,但在B和C上面。让我们称它为E。你将D和E作为A的子类,B和C作为E的子类。在你的概念中有两件事可以做 如果所有的B,C和D都需要从A中输入,并且有一个方法不应该从A中输入D,那么你可能

例如,我们有一个名为a的基类和三个名为B C D的子类,都是a的继承。如果我想要某个方法只出现在B和C中,而不出现在D中。我应该把这个方法放在哪里

如果我把它放在A中,D将有它不需要的方法


如果我把它放在B和C中,我重复我自己的话。

如果它是B和C中可见的“相同”方法,听起来你需要在A下面的层次结构中添加另一个类,但在B和C上面。让我们称它为E。你将D和E作为A的子类,B和C作为E的子类。

在你的概念中有两件事可以做

  • 如果所有的B,C和D都需要从A中输入,并且有一个方法不应该从A中输入D,那么你可能需要重新计算A中需要输入什么方法来避免这种情况
  • 如果仍然无法在A中进行任何更改,并且仍然需要从A继承D,那么最好引发未实现/不支持的错误,如下所示

    class D(object):
    """docstring for D"""
    def __init__(self, arg):
        super(D, self).__init__()
        self.arg = arg
    
    def methodThatWasNotSupposedToComeHere(some_params ):
        raise NotImplementedError("This is not supported")
    

  • 与其他语言不同的是,没有“标准”的方法来实现这一点。
    您可以重写它,使其引发异常

    class Human( object ):
        def walk( self ):
            print 'walking...'
    
    class Baby(Human)
        def walk( self ):
            raise NotImplementedError("can't right now")
    
    class Teenager(Human):
    ...
    

    Python在这方面是一种非常灵活的语言

    您可以在C和D类范围之外定义方法,并将其分别绑定到它们:

    class A(object):
        pass
    
    class B(A):
        pass
    
    def method(self):
        print '%s.method()' % type(self).__name__
    
    class C(A):
        method = method
    
    class D(A):
        method = method
    
    c = C()
    d = D()
    
    c.method() # prints "C.method()"
    d.method() # prints "D.method()"
    
    print c.method # prints "<bound method C.method of <__main__.C object at 0x????????>>"
    print d.method # prints "<bound method D.method of <__main__.D object at 0x????????>>"
    
    A类(对象):
    通过
    B(A)类:
    通过
    def方法(自我):
    打印'%s.方法()'%type(self)。\u\u名称__
    C(A)类:
    方法
    D(A)类:
    方法
    c=c()
    d=d()
    c、 方法()#打印“c.方法()”
    d、 方法()#打印“d.method()”
    打印c.方法#打印“”
    打印d.方法#打印“”
    
    您可以引入一个从a继承的新类,在此类中定义您的方法,并从此新类继承C和D。这是“经典”OOP方法

    您可以在A中实现您的方法,并在B中重写它,告诉它引发一些异常。最好是在抽象类中使用非实现错误以外的东西-AttributeError似乎是更好的候选者。请注意,如果您不打算在代码中实例化类,则.method引发NotImplementedError是有意义的,它可以有效地将类转换为抽象类


    您可以求助于duck类型化,只需在C和D中实现两个相同的方法。Python在duck类型化方面很强大,但在复制代码方面并不强大,因此在这种情况下,这可能不是最好的解决方案。

    也许D不应该继承一个?@Dan是的,对OOP来说有点陌生。很好,我知道您已经接受了,但很高兴您选择了@Wyzard。他的答案是OOP的传统答案,它跨越了所有OO语言。不过,TimplementedError是用于抽象类的。有些IDE会因为将类与此类方法一起使用而臭名昭著。@Lav
    用于抽象类
    你能提供一些证据吗?Python官方文档足够吗?:-)特别是,@saifas如果抱歉,忘记在前面的评论中包括您的名字。无论如何,我很确定以这种方式使用NotImplementedError也违反了至少一个PEP,并做了一些额外的研究,但不,这是合法的。仍然不能改变这样一个事实,即任何查看代码的人都会立即假定一个具有NotImplementedError提升方法的类是一个抽象类。没有必要制造更多的混乱。:-)对我来说很有用,也很有意义