29

我经常有以下代码导致变量阴影或局部变量的乘法

def whenadult(age):
    return 18 - age

age = 5
needtowait = whenadult(age)

age在传递给函数时与主代码中具有相同的逻辑角色,所以我想避免l_age在 whenadult 中创建类似的东西。

解决“阴影与变量乘法”困境的pythonic方法是什么?

更新:跟进一些评论我想明确表示我正在寻找 Python 最佳实践(而不是本地与全局变量范围)

4

2 回答 2

53

局部变量(和函数参数)age恰好与程序中其他地方的变量同名这一事实无关紧要。局部变量的全部意义在于它们只存在于定义它们的函数的局部范围内。

局部变量与其他地方用作参数的变量同名这一事实尤其不是问题。事实上,它在现实生活中的代码中很常见。例如,选择一个随机的 stdlib 模块,即 3.3 版本cmd,该Cmd.onecmd方法有一个名为 的变量line,并将其作为参数传递给该self.default方法,该方法将其绑定到一个也名为 的参数line

如果您没有同名的局部变量,则用于参数的变量恰好是您可以访问的全局变量这一事实不是问题,除非您真的想访问该全局变量。您不想在现有代码中出现,而且几乎从不应该这样做。在这种情况下,在大多数现实世界的情况下,这只是一个巧合,没有任何意义,也没有任何影响,而不是你必须解决的问题。


您遇到的问题是 PyCharm 无法猜测您是否希望全局age可以在whenadult. 是否有可能(如果不是在这种微不足道的情况下,也许在更复杂的情况下)人类可能会同样感到困惑,从而减慢他对代码的理解速度?或者有一天你必须在某个环境中编写代码,你的代码审查员或老师或任何人会拒绝你的代码,因为它没有通过一些没有警告的 linter?也许。

但实际上,在任何这样的环境中,他们可能首先会抱怨您使用全局变量。你真的不需要在这里。唯一的原因age是全局是顶级代码必须可以访问它。如果您将该代码移动到一个函数中,age则可以成为该函数中的本地代码。例如:

def whenadult(age):
    return 18 - age

def main():
    age = 5
    needtowait = whenadult(age)

main() # possibly with an if __name__ == '__main__' guard

这将使 PyCharm 以及任何 linter 工具以及任何容易混淆或思维固执的人类读者都感到高兴。它甚至会让你的代码更快一点。另一方面,要阅读的代码更多——只有三行和一个缩进,但整个程序只有八行长。因此,您可以根据具体情况进行权衡。

于 2013-11-11T09:03:35.003 回答
5

每当我在 PyCharm 中收到阴影变量的警告时。我会尝试重命名局部变量以使用下划线前缀作为约定。这是除了将全局变量包装到 main() 函数之外的另一种考虑方式。

    def whenadult(_age):
        return 18 - _age

    age = 5
    needtowait = whenadult(age)
于 2015-09-16T15:50:17.847 回答