导入变量的范围

scope of imported variables

我在 python3.8 脚本中遇到过这样的情况,在从外部文件导入一堆变量后,在某些函数中可以正常访问它们,而在其他函数中则不能。例如。一个常量 min_time_n_clicks 在文件 tm_constants.py 中用一个简单的声明定义,

min_time_n_clicks=10

请原谅,这不是一个可重现的例子,因为完整的代码很长,它试图展示我所击中的东西:在一个函数中 check_scope 我可以通过使用 from tm_constants import * 而另一个函数 check_for_limiting 看不到它们 - 它命中

UnboundLocalError: local variable 'min_time_n_clicks' referenced before assignment

为什么会这样?我从不使用 del 等删除变量,在我使用的 pycharm 调试器中,即使在违规函数的范围内,也可以看到和评估违规变量 (min_time_n_clicks)。使用点表示法访问是否是首选方法,如果是,为什么?

from tm_constants import *
import tm_constants

def check_scope():

    print(f'ok: {min_time_n_clicks}')
    print(f'ok: {tm_constants.min_time_n_clicks}')

def check_for_limiting():
    print(tm_constants.min_time_n_clicks)
    tm_constants.min_time_n_clicks = 0  # ok 
    print(min_time_n_clicks)
    min_time_n_clicks = 0 # not ok !!!

这将产生一个 UnboundLocalError:

def check_for_limiting(browser):
    print(min_time_n_clicks)
    min_time_n_clicks = 0

编译函数定义时,解析器根据赋值将min_time_n_clicks标记为局部变量。这意味着 all 在函数作用域中使用名称是指局部变量,即使是那些在 之前 赋值的使用。即使在运行时无法达到赋值也是如此:

def check_for_limiting(browser):
    print(min_time_n_clicks)  # Still raises an UnboundLocalError
    if False:
        min_time_n_clicks = 0

如果你的意图是分配给全局变量,你需要使用global来标记名称为全局:

def check_for_limiting(browser):
    global min_time_n_clicks

    print(min_time_n_clicks)
    min_time_n_clicks = 0

点分访问没有问题,因为在这种情况下没有名为 min_time_n_clicks 的变量;只有全局名称 tm_constants 引用具有名为 min_time_n_clicks 属性 的对象。进一步注意,直接分配给 min_time_n_clicks 而不是 更改 tm_constants.min_time_n_clicks 的值,因为它们是对同一对象的两个不同引用。更改一个引用不会更改另一个。