什么是避免阴影变量的pythonic方法?

时间:2013-11-11 08:45:35

标签: python variables scope

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

def whenadult(age):
    return 18 - age

age = 5
needtowait = whenadult(age)

age在传递给主函数中的函数时具有相同的逻辑角色,因此我希望避免在whenadult中创建类似l_age的内容。

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

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

2 个答案:

答案 0 :(得分:44)

本地变量(和函数参数)age碰巧与程序中其他位置的变量同名,这一事实无关紧要。局部变量的重点在于它们只存在于它们所定义的函数的局部范围内。

本地变量与其他地方用作参数的变量同名的事实是尤其不是问题。实际上,它在现实代码中非常常见。例如,选择随机stdlib模块,cmd的3.3版本,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工具,以及任何容易混淆或严格思考的人类读者。它甚至可以让你的代码更快一点。另一方面,只有三行和一个缩进的代码更多,但整个程序只有八行长。因此,您可以根据具体情况进行权衡。

答案 1 :(得分:4)

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

    def whenadult(_age):
        return 18 - _age

    age = 5
    needtowait = whenadult(age)