第32章-python代码分析

python代码分析可能是一个很重的主题,但它对于使程序变得更好非常有帮助。有几个python代码分析器可以用来检查代码并查看它们是否符合标准。皮林特可能是最受欢迎的。它是非常可配置、可定制和可插拔的。它还检查您的代码是否符合PEP8(Python核心的官方样式指南),并查找编程错误。

请注意,pylint会根据大多数(但不是所有)pep8的标准检查代码。我们将花一点时间学习另一个称为 石膏片 .

开始使用皮林特

pylint包不包含在python中,因此您需要转到python包索引(pypi)或包的网站来下载它。您可以使用以下命令来完成所有工作:

pip install pylint

如果一切按计划进行,你现在应该 皮林特 已安装,我们将准备继续。

分析代码

一旦安装了pylint,就可以在命令行上运行它,而不需要任何参数来查看它接受的选项。如果这不起作用,您可以这样键入完整路径:

c:\Python34\Scripts\pylint

现在我们需要一些代码来分析。这是一段有四个错误的代码。将此保存到名为 crummy_code.py

import sys

class CarClass:
    """"""

    def __init__(self, color, make, model, year):
        """Constructor"""
        self.color = color
        self.make = make
        self.model = model
        self.year = year

        if "Windows" in platform.platform():
            print("You're using Windows!")

        self.weight = self.getWeight(1, 2, 3)

    def getWeight(this):
        """"""
        return "2000 lbs"

你能在不运行代码的情况下发现错误吗?让我们看看皮林特是否能找到问题!

pylint crummy_code.py

当你运行这个命令时,你会看到很多输出被发送到你的屏幕上。下面是一个部分示例:

c:\py101>c:\Python34\Scripts\pylint crummy_code.py
No config file found, using default configuration
************* Module crummy_code
C:  2, 0: Trailing whitespace (trailing-whitespace)
C:  5, 0: Trailing whitespace (trailing-whitespace)
C: 12, 0: Trailing whitespace (trailing-whitespace)
C: 15, 0: Trailing whitespace (trailing-whitespace)
C: 17, 0: Trailing whitespace (trailing-whitespace)
C:  1, 0: Missing module docstring (missing-docstring)
C:  3, 0: Empty class docstring (empty-docstring)
C:  3, 0: Old-style class defined. (old-style-class)
E: 13,24: Undefined variable 'platform' (undefined-variable)
E: 16,36: Too many positional arguments for function call (too-many-function-args)
C: 18, 4: Invalid method name "getWeight" (invalid-name)
C: 18, 4: Empty method docstring (empty-docstring)
E: 18, 4: Method should have "self" as first argument (no-self-argument)
R: 18, 4: Method could be a function (no-self-use)
R:  3, 0: Too few public methods (1/2) (too-few-public-methods)
W:  1, 0: Unused import sys (unused-import)

让我们花点时间把这件事讲清楚。首先,我们需要弄清楚字母的含义:C代表约定,R代表重构,W代表警告,E代表错误。pylint发现3个错误,4个约定问题,2行可能值得重构,1个警告。3个错误加上警告是我要找的。我们应该努力使这个零碎的代码更好,减少问题的数量。我们将修复导入并更改get weight函数以获取权重,因为方法名不允许使用camelcase。我们还需要修复调用以获得权重,以便它传递正确数量的参数,并修复它,使其具有“self”作为第一个参数。以下是新代码:

# crummy_code_fixed.py
import platform

class CarClass:
    """"""

    def __init__(self, color, make, model, year):
        """Constructor"""
        self.color = color
        self.make = make
        self.model = model
        self.year = year

        if "Windows" in platform.platform():
            print("You're using Windows!")

        self.weight = self.get_weight(3)

    def get_weight(self, this):
        """"""
        return "2000 lbs"

让我们对pylint运行这段新代码,看看我们改进了多少结果。为了简洁起见,我们将再次显示第一部分:

c:\py101>c:\Python34\Scripts\pylint crummy_code_fixed.py
No config file found, using default configuration
************* Module crummy_code_fixed
C: 1,0: Missing docstring
C: 4,0:CarClass: Empty docstring
C: 21,4:CarClass.get_weight: Empty docstring
W: 21,25:CarClass.get_weight: Unused argument 'this'
R: 21,4:CarClass.get_weight: Method could be a function
R: 4,0:CarClass: Too few public methods (1/2)

帮了大忙!如果我们添加docstring,我们可以将问题的数量减半。现在我们准备好看一看Pyflakes了!

Pyflakes入门

这个 石膏片 项目是被称为divmod项目的一部分。pyflakes实际上并不执行它检查的代码,就像pylint不执行它分析的代码一样。您可以使用pip安装pyflakes,也可以从源代码轻松安装。

我们将首先针对与Pylin一起使用的同一段代码的原始版本运行Pyflakes。这里又是:

import sys

class CarClass:
    """"""

    def __init__(self, color, make, model, year):
        """Constructor"""
        self.color = color
        self.make = make
        self.model = model
        self.year = year

        if "Windows" in platform.platform():
            print("You're using Windows!")

        self.weight = self.getWeight(1, 2, 3)

    def getWeight(this):
        """"""
        return "2000 lbs"

如前一节所述,这段愚蠢的代码有4个问题,其中3个问题将阻止程序运行。让我们看看有什么皮屑!尝试运行以下命令,您将看到以下输出:

c:\py101>c:\Python34\Scripts\pyflakes.exe crummy_code.py
crummy_code.py:1: 'sys' imported but unused
crummy_code.py:13: undefined name 'platform'

虽然pyflakes在返回这个输出时速度非常快,但它没有找到所有错误。这个 获取权重 方法调用传递的参数太多,并且 获取权重 方法本身的定义不正确,因为它没有 self 参数。好吧,你可以随意称第一个论点,但根据惯例它通常被称为 self .如果您根据Pyflakes告诉您的内容修改了代码,那么代码仍然无法工作。

总结

下一步将尝试对您自己的一些代码或像sqlacalchemy这样的python包运行pylint和pyflakes,并查看输出结果。使用这些工具,您可以了解很多关于您自己的代码。pylint与许多流行的python-ide集成,如wingware、editra和pydev。你可能会发现皮林特的一些警告很烦人,甚至不适用。有一些方法可以通过命令行选项来抑制诸如拒绝警告之类的内容。或者你可以使用 -generate-rcfile 创建一个示例配置文件,它将帮助您控制pylint。请注意,pylint和pyflakes不会导入代码,因此您不必担心不良的副作用。