135

我在一些代码上运行 Pylint,并收到错误“公共方法太少(0/2)”。这条消息是什么意思?

Pylint文档没有帮助:

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

4

4 回答 4

145

该错误基本上表明类不只是存储数据,因为您基本上将类视为字典。类应该至少有几个方法来操作它们所持有的数据。

如果您的课程如下所示:

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

考虑使用字典或 anamedtuple代替。虽然如果一个类看起来是最好的选择,那就使用它。Pylint 并不总是知道什么是最好的。

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

于 2012-12-25T04:30:49.620 回答
52

如果您正在扩展一个类,那么我的建议是系统地禁用此警告并继续,例如,在 Celery 任务的情况下:

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

    ...             

即使你只是扩展一个功能,你肯定需要一个类来让这个技术发挥作用,而且扩展绝对比破解第三方类更好!

于 2016-03-18T19:49:09.893 回答
26

这是皮林特盲法的另一个例子。

“类不是用来存储数据的”——这是一个错误的陈述。字典并不适合所有事情。类的数据成员是有意义的,字典项是可选的。证明:你可以dictionary.get('key', DEFAULT_VALUE)阻止 a 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(Py 3.7+)

根据 hwjp 的评论,我还建议dataclasses

https://docs.python.org/3/library/dataclasses.html

这几乎和 一样好attrs,并且是标准库机制(“包含电池”),没有额外的依赖项,除了 Python 3.7+。

上一个答案的其余部分

NamedTuple不是很好 - 特别是在 Python 3 之前typing.NamedTuplehttps ://docs.python.org/3/library/typing.html#typing.NamedTuple

  • 您绝对应该检查“派生自NamedTuple”模式。Python 2 -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,但小心,设置器可能假设其他字段已经初始化,然后你需要在构造函数)。

于 2018-06-20T07:39:25.147 回答
6

当你的老板期望单一责任原则时,这很难,但 Pylint 拒绝了。所以向你的类添加第二个方法,这样你的类就违反了单一责任原则。在旁观者的眼中,您应该在多大程度上采取单一责任原则。

我的修复

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

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

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

问题解决了,但不是我的同事整天都在争论规范,而不是继续下去,就像生死攸关一样。

于 2019-04-01T09:10:04.760 回答