【问题标题】:Why pep8/flake8 cannot detect unbound local variable only declared in if branch为什么 pep8/flake8 无法检测仅在 if 分支中声明的未绑定局部变量
【发布时间】:2013-10-21 08:22:21
【问题描述】:

给定一个简单的代码,如下所示:

def func(flag):
    if flag:
        seq = range(3)
    return seq[1]

pep8 和 flake8 都认为这段代码不错。为什么会发生这种情况? seq 仅在 if 子句下定义。

【问题讨论】:

  • pep8 和 flake8 并不是真正的代码分析器,它们更像是样式检查器。
  • seq 可以在函数外部定义。
  • @Fabian:不,它不能 - UnboundLocalError: local variable 'seq' referenced before assignment
  • 为此您需要一个更复杂的分析器。 PyCharm 检测到这个可能的错误。
  • @Fabian:现在尝试在函数中对foo 进行不可访问的赋值,这就是导致foo 成为局部变量的原因

标签: python pep8 flake8


【解决方案1】:

我对@9​​87654322@ 的设计和实现没有任何具体知识,但检测条件未定义变量一般是一件棘手的事情。例如,考虑以下代码:

def func(value):
    if value < 2:
        raise ValueError()
    for p in generate_primes():
        if value % p == 0:
            smallest_prime_factor = p
            break
    do_something_with(smallest_prime_factor)

现在,程序员知道只要你传入一个整数,其中一项测试就会通过。静态分析工具不知道这一点。那么你的工具要做什么呢?

  • 需要在循环中使用else 子句(在这种情况下,除非您注入不满足generate_primes 合同的generate_primes 模拟版本,否则您将无法获得测试的完整代码覆盖率)
  • 需要在循环之前使用smallest_prime_factor = 1 之类的东西进行初始化(这会误导代码的读者,即有一种情况需要处理,结果没有在循环中初始化)。
  • 禁用仅对该变量的检查 (https://github.com/cburroughs/pep8.py/issues/12)
  • 不要诊断条件未定义的变量(这意味着您会遗漏一些错误)。

在我看来,pep8 似乎选择了简单而保守的选择:它不会诊断出可能不正确的东西。解决方法是不要仅仅依赖静态分析工具,当然不要仅仅依赖主要用于检测样式问题而不是代码正确性问题的工具。编写具有完整代码覆盖率的测试 - 然后对于您的代码,flag 为 false 的测试将抛出,诊断您的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2012-01-27
    • 2023-03-12
    • 2023-03-05
    • 2017-02-11
    • 2023-03-15
    相关资源
    最近更新 更多