Pylint 的“公共方法太少”消息是什么意思?

我正在一些代码上运行 Pylint,收到错误“ Too few public method (0/2)”。这条消息是什么意思?

Pylint 文档没有帮助:

当一个类的公共方法太少时使用,所以要确保它真的值得使用。

99325 次浏览

这个错误基本上说明类不是用来存储 只是数据的,因为您基本上是把类当作字典来对待的。类应该至少有几个方法来操作它们所持有的数据。

如果你的班级是这样的:

class MyClass(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar

考虑使用字典或 namedtuple代替。尽管如果一个类看起来是最好的选择,使用它。皮林特并不总是知道什么是最好的。

请注意,namedtuple是不可变的,以后不能修改实例化时分配的值。

如果你正在扩展一个类,那么我的建议是系统地禁用这个警告并继续前进,例如,对于芹菜任务:

class MyTask(celery.Task):  # pylint: disable=too-few-public-methods
"""base for My Celery tasks with common behaviors; extends celery.Task


...

即使您只是扩展一个函数,也肯定需要一个类来实现这个技术函数,而且扩展肯定比黑客攻击第三方类要好!

这是 Pylint 盲目规则的另一个例子。

“类不是用来存储数据的”——这是一个错误的陈述。字典不是万能的。类的数据成员是有意义的,字典项是可选的。证明: 您可以执行 dictionary.get('key', DEFAULT_VALUE)来防止 KeyError,但是没有默认的简单 __getattr__

使用结构体的推荐方法

我需要更新我的答案。现在——如果你需要一个 struct,你有两个很好的选择:

A)使用 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中也是如此)等等。

B)使用 dataclasses(Py3.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 叫 Tuple

  • 您肯定应该检查“从 NamedTuple派生的类”模式。 Python2-由字符串描述创建的 namedtuples-丑陋、糟糕,而且“在字符串文字内编程”愚蠢。

我同意目前的两个答案(“考虑使用其他东西,但 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

上面你有只读属性,这对值对象是可以的(例如,在域驱动设计) ,但是你也可以提供设置器-这样你的类将能够负责你有的字段-例如做一些验证等(如果你有设置器,你可以分配使用他们在构造函数,即,self.foo = foo而不是直接 self._foo = foo,但是小心,设置器可能假设其他字段已经初始化,然后你需要自定义验证在构造函数)。

当你的老板期望 单一责任原则单一责任原则的时候,这很难,但是 Pylint 说不。因此,向您的类中添加第二个方法,这样您的类就违反了单一责任原则。你应该在单一责任原则上走多远取决于旁观者的看法。

我的药

我在类中添加了一个额外的方法,所以它现在做两件事。

def __str__(self):
return self.__class__.__name__

我只是想知道现在是否需要将我的类分成两个独立的文件,也许还需要模块。

这个问题已经解决了,但是我的同事们整天都在争论这个规范,而不是像处理生死攸关的问题一样处理它。