pylint的“公共方法太少”消息意味着什么

时间:2012-12-25 03:22:03

标签: python pylint

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

  

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

4 个答案:

答案 0 :(得分:99)

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

如果您的课程如下:

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

请考虑使用字典或namedtuple。虽然如果一个类似乎是最好的选择,请使用它。 pylint并不总是知道什么是最好的。

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

答案 1 :(得分:37)

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

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

    ...             

即使你只是扩展一个函数,你肯定需要一个类来使这个技术起作用,并且扩展肯定比攻击第三方类更好!

答案 2 :(得分:5)

这是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__,只读对象(即使在Python 2中也可以替换namedtuples)。

b)使用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派生的类”模式。 Python 2 –由字符串描述创建的namedtuples –丑陋,糟糕,并且“在字符串文字中编程”是愚蠢的。

我同意当前的两个答案(“考虑使用其他方法,但pylint并不总是正确的” –接受的答案,以及“使用pylint抑制注释”),但是我有自己的建议。

让我再指出一次:有些类是 just 来存储数据。

现在还可以选择<考虑> -使用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来说是可以的(例如,像Domain Driven Design中的属性),但是您也可以提供setter-这样,您的课程将能够对您拥有的字段负责-例如进行一些验证等。(如果您有设置器,则可以在构造函数中使用它们进行分配,即self.foo = foo而不是直接的self._foo = foo,但请注意,设置器可能会假定其他字段是已经初始化,然后需要在构造函数中进行自定义验证。

答案 3 :(得分:1)

我在课堂上添加了一个额外的方法

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

问题解决了