pylint 没有发现明显的错误

pylint does not catch obvious error

这是我的代码:

class Horse:

    def talk(self):
        print 'Hihaaa!'


class Farm:

    def __init__(self, animal):
        self.animal = animal

    def animaltalk(self):
        self.animal.sing()


def main():
    horse = Horse()
    farm = Farm(horse)
    farm.animaltalk()


main()

这是我的 pylint:

$ pylint --version
No config file found, using default configuration
pylint 1.4.3, 
astroid 1.3.6, common 0.63.2
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2]

这是 pylint 的输出:

$ pylint farm.py

************* Module farm
C:  1, 0: Missing module docstring (missing-docstring)
C:  1, 0: Missing class docstring (missing-docstring)
C:  1, 0: Old-style class defined. (old-style-class)
W:  1, 0: Class has no __init__ method (no-init)
C:  3, 4: Missing method docstring (missing-docstring)
R:  3, 4: Method could be a function (no-self-use)
R:  1, 0: Too few public methods (1/2) (too-few-public-methods)
C:  7, 0: Missing class docstring (missing-docstring)
C:  7, 0: Old-style class defined. (old-style-class)
C: 12, 4: Missing method docstring (missing-docstring)
R:  7, 0: Too few public methods (1/2) (too-few-public-methods)
C: 16, 0: Missing function docstring (missing-docstring)

我对所有这些 warnings/messages 都不感兴趣,除非它们确实与我的问题有关,即:pylint 无法告诉我 self.animal.sing()错误(应该是self.animal.talk())。

我需要这个的原因是,在复杂的代码中,大型重构会导致 pylint 无法捕获的错误,这意味着捕获它们的唯一方法是测试;不幸的是,我没有对所有代码路径进行测试。更好的 pylint 分析将大大有助于解决我的代码中的明显问题。

请将其报告给 pylint 的错误跟踪器:https://bitbucket.org/logilab/pylint/。这实际上是一个问题,因为在 pylint 中,实例不知道它们的参数。这应该很容易修复。

Is there a way of forcing pylint to perform a deeper analysis

没有

or is this a fundamental limitation of the Python language?

嗯,理论上可以继续编写越来越智能的分析器。您当然可以编写一个 Pylint 插件来捕获您的特定错误(但在其他类似情况下会失败)。 PySonar2 可能涵盖也可能不涵盖您的情况。

Or is there a better pattern to code this kind of functionality (an object collecting other pre-instantiated objects), so that pylint can perform better error-checking?

好问题。我发现通常有一种方法可以调整代码以使 Pylint 对它更有用。然而,在你的情况下,我能想到的最好的方法是使用 Farm 的特殊子类,例如 SingingFarmHorseFarm,如下所示:

class Farm:

    def __init__(self, animal):
        self.animal = animal


class SingingFarm(Farm):

    def animalsing(self):
        self.animal.sing()

然后,如果您在 Farm 的错误类型上调用 animalsing,Pylint 将会抱怨。当然,这是一种非常有限的方法,可能不适合您。

不过,我相信 grep 是唯一可以在重构 Python 代码时为您提供任何保证的工具。如果我使我的符号足够独特(即 specific_term 而不是 value),并尽可能避免动态属性访问,至少我可以指望 grep 获得 99%顺便。