"传递"在Python中进一步向下子类的抽象方法的实现?

时间:2017-10-18 00:48:01

标签: python pylint

抱歉,我无法想出一个更好的方式来标题!

基本上,我想要一个抽象基类,然后是一个没有实现抽象方法的子类,然后是 的子类, 实现该方法。例如,它可能更容易:

import abc
class A(abc.ABC):
  def __init__(self, some_var):
    self.some_var = some_var

  @abc.abstractmethod
  def some_method(self):
    pass

class B(A):
  def some_b_method(self):
    print("Hello")

class C(B):
  def some_method(self):
    self.some_b_method()
    print(self.some_var)

c = C('world')
c.some_method()

这就是我期望它的工作方式,但对于Pylint报告warning 0223以上的 B 类。

如果修改 B 类以包含以下内容,Pylint不会给我任何问题,但代码重复似乎有误:

@abc.abstractmethod
def some_method(self):
  pass

是否有正确的"办法?我无法找到答案。

4 个答案:

答案 0 :(得分:0)

“正确”方式是class B不会从abstract class A继承;如果是,B必须实现abstract methods

的所有A

class C继承class Aclass BB独立于A的另一种方法:

import abc
class A(abc.ABC):
  def __init__(self, some_var):
    self.some_var = some_var

  @abc.abstractmethod
  def some_method(self):
    pass

class B():
  def some_b_method(self):
    print("Hello")

class C(A, B):
  def some_method(self):
    self.some_b_method()
    print(self.some_var)

c = C('world')
c.some_method()

答案 1 :(得分:0)

如果立即未实现该方法,则不应使用抽象方法定义抽象基类。更好的选择是在没有抽象方法的情况下定义ABC,并定义包含该方法的mixin类。您可以从class B继承class A,然后从class C和mixin继承class B

import abc
class A(abc.ABC):
    def __init__(self, some_var):
        self.some_var = some_var

class MixinA(abc.ABC):
    @abc.abstractmethod
    def some_method(self):
        pass

class B(A):
    def some_b_method(self):
        print("Hello")

class C(B, MixinA):
    def some_method(self):
        self.some_b_method()
        print(self.some_var)

c = C('world')
c.some_method()

# returns:
Hello
world

# list the methods:
[m for m in dir(c) if not m.startswith('_')]
# returns:
['some_b_method', 'some_method', 'some_var']

答案 2 :(得分:0)

当然,Python可以这样做:只需在中间类的方法定义中引发NotImplementedError

class BaseClass :

    def method(...) :
        ... actually do something ...
    #end method

#end BaseClass

class Subclass(BaseClass) :

    def method(...) :
        raise NotImplementedError
    #end method

    ...

#end Subclass

class SubSubclass(Subclass) :

    def method(...) :
        ... actually do something else ...
    #end method

#end SubSubclass

这听起来像你在找什么?

答案 3 :(得分:0)

虽然拥有抽象类的继承层次结构可能违背某些人的风格,但我认为您当前的代码很好。如果你不想,你不需要改变任何东西。

Pylint正在给你一个警告,因为你做某些事情在某些情况下可能是一个错误,但在其他情况下可能没问题。如果您希望B成为具体类,则从A继承抽象方法而不覆盖它将是一个问题。但是,如果您希望BA一样抽象,那么它就会发现它不会覆盖它继承的抽象方法。

因此,您可以忽略Pylint中的警告,也可以通过在文件中添加注释# pylint: disable=W0223来取消警告。根据评论的确切位置,我相信它可以禁用仅针对一个特定类或整个模块的警告。