“传递”一个抽象方法的实现通过在Python中进一步下去?
对不起,我想不出一个更好的方式来标题!“传递”一个抽象方法的实现通过在Python中进一步下去?
基本上,我想一个抽象基类,则一个子类的一个不起实现抽象方法,则一个子类的该,其不实现该方法。这也可能是用一个例子更容易:
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。
pylint的不给我任何问题,如果我修改乙类包括以下内容,但重复代码似乎是错误的:
@abc.abstractmethod
def some_method(self):
pass
是否有一个“正确”的方法是什么?我找不到答案。
该“正确”方式是,class B
不从abstract class A
继承;如果这样做,B
必须实现的A
另一种方法都abstract methods
它有来自class A
class C
继承和class B
,具有独立的A
B
:
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()
你不应该定义一个抽象基如果你是立即将不执行该方法的抽象方法类。最好的办法是定义没有抽象方法的ABC,并且定义一个包含该方法的mixin类。您可以从class A
子类class B
,然后子类class C
class B
和mixin。
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']
当然,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
这听起来像是你在找什么?
尽管可能会违背某些人的风格来拥有抽象类的继承层次结构,但我认为您当前的代码很好。如果你不想要,你不需要改变任何东西。
Pylint给你一个警告,因为你正在做某些事情,在某些情况下可能是错误的,但在其他情况下可能是OK的。如果您希望B
成为一个具体类,则从A
继承抽象方法而不会覆盖它将会是一个问题。但是如果你期望B
像A
一样是抽象的,那么它会发现它不覆盖它继承的抽象方法。
因此,您可以忽略来自Pylint的警告,或者通过在文件中添加注释# pylint: disable=W0223
来取消警告。具体取决于放置评论的位置,我相信它可以禁用仅针对特定类或整个模块的警告。