抱歉,我无法想出一个更好的方式来标题!
基本上,我想要一个抽象基类,然后是一个没有实现抽象方法的子类,然后是 的子类, 实现该方法。例如,它可能更容易:
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
是否有正确的"办法?我无法找到答案。
答案 0 :(得分:0)
“正确”方式是class B
不会从abstract class A
继承;如果是,B
必须实现abstract methods
A
让class C
继承class A
和class B
,B
独立于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
继承抽象方法而不覆盖它将是一个问题。但是,如果您希望B
与A
一样抽象,那么它就会发现它不会覆盖它继承的抽象方法。
因此,您可以忽略Pylint中的警告,也可以通过在文件中添加注释# pylint: disable=W0223
来取消警告。根据评论的确切位置,我相信它可以禁用仅针对一个特定类或整个模块的警告。