我在某些代码上运行pylint,并收到错误“公共方法太少(0/2)”。此消息是什么意思?该pylint的文档也没有什么帮助:
当类的公共方法太少时使用,因此请确保它确实值得。
我在某些代码上运行pylint,并收到错误“公共方法太少(0/2)”。此消息是什么意思?该pylint的文档也没有什么帮助:
当类的公共方法太少时使用,因此请确保它确实值得。
Answers:
该错误基本上表明类并不意味着仅存储数据,因为您基本上将类视为字典。类至少应具有几种方法来处理它们所保存的数据。
如果您的班级看起来像这样:
class MyClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
考虑使用字典或namedtuple
替代字典。尽管如果一堂课似乎是最好的选择,请使用它。pylint并不总是知道什么是最好的。
请注意,这namedtuple
是不可变的,实例化时分配的值以后不能修改。
dict
或namedtuple
。当您想向对象添加一些逻辑时使用一个类(例如,您希望在创建对象时发生一些事情,在添加对象时需要发生一些特殊的事情,您想要对它执行一些操作,控制其发生方式显示,等等)
namedtuple
很烂-除了语法丑陋之外,您无法记录下来或轻松提供默认值。
namedtuple
我都会后悔这个决定。允许命名访问和索引访问属性都是不一致的。
如果您要扩展课程,那么我的建议是系统地禁用此警告并继续进行,例如,在Celery任务中:
class MyTask(celery.Task): # pylint: disable=too-few-public-methods
"""base for My Celery tasks with common behaviors; extends celery.Task
...
即使仅扩展单个函数,您也绝对需要一个类来使该技术起作用,并且扩展绝对比黑客第三方类更好!
min-public-methods=0
的[BASIC]
部分中进行设置。这使您可以将其与所有disable=
内容(放在[MESSAGE CONTROL]
)中中,我发现可以更轻松地添加有关启用和禁用内容以及配置更改原因的详细注释。
这是pylint
的盲目规则的另一种情况。
“类并不意味着存储数据”-这是一个错误的陈述。字典并不能满足所有需求。类的数据成员是有意义的,字典项是可选的。证明:您可以dictionary.get('key', DEFAULT_VALUE)
防止KeyError
,但__getattr__
默认情况下不简单。
我需要更新我的答案。现在-如果需要a struct
,则有两个不错的选择:
attrs
这些是为此的库:
https://www.attrs.org/en/stable/
import attr
@attr.s
class MyClass(object): # or just MyClass: for Python 3
foo = attr.ib()
bar = attr.ib()
您得到的额外好处是:不编写构造函数,默认值,验证__repr__
,只读对象(namedtuples
即使在Python 2中也要替换),等等。
dataclasses
(Py 3.7+)根据hwjp的评论,我还建议 dataclasses
:
https://docs.python.org/3/library/dataclasses.html
这几乎和 attrs
,并且是标准的库机制(“包含电池”),没有额外的依赖关系,但Python 3.7+除外。
NamedTuple
并不是很好-特别是在python 3之前typing.NamedTuple
:https :
//docs.python.org/3/library/typing.html#typing.NamedTuple-
您一定要检查“从NamedTuple
模式”。namedtuples
从字符串描述创建的Python 2 丑陋,糟糕,并且“在字符串文字中编程”是愚蠢的。
我同意两个当前的答案(“考虑使用其他东西,但是pylint并不总是正确的” –接受的答案,以及“使用pylint抑制评论”),但是我有自己的建议。
让我再指出一次:一些类意味着 仅用于存储数据。
现在还要考虑的选项-使用property
-ies。
class MyClass(object):
def __init__(self, foo, bar):
self._foo = foo
self._bar = bar
@property
def foo(self):
return self._foo
@property
def bar(self):
return self._bar
在上面,您具有只读属性,对于Value Object来说,这是可以的(例如,像域驱动设计中的属性),但是您也可以提供setter-这样,您的类将能够对自己拥有的字段负责进行一些验证等。(如果有设置器,则可以在构造函数中使用它们进行赋值,即self.foo = foo
代替Direct self._foo = foo
,但要小心,设置器可能会假定其他字段已经初始化,然后需要在构造函数中进行自定义验证) 。
attrs
库,它实际上是创建dataclasses
模块的蓝图。
namedtuples
对于继承有奇怪的语法...要求每个使用一个类的类都知道这是一个命名的元组,并使用__new__
代替__init__
。 dataclasses
没有这个限制