python内部导入函数隐藏现有变量

python内部导入函数隐藏现有变量,python,python-import,Python,Python Import,我正在处理一个多子模块项目中的一个奇怪的“UnboundLocalError:local variable referenced before assignment”问题,并将其精简为以下代码段(使用标准库中的日志模块): 其中有以下输出(我尝试了python 2.7和3.3): INFO:root:foo 回溯(最近一次呼叫最后一次): 文件“import-test01.py”,第16行,在 bar() 文件“import-test01.py”,第7行,条形图 logging.info('ba

我正在处理一个多子模块项目中的一个奇怪的“UnboundLocalError:local variable referenced before assignment”问题,并将其精简为以下代码段(使用标准库中的日志模块):

其中有以下输出(我尝试了python 2.7和3.3):

INFO:root:foo
回溯(最近一次呼叫最后一次):
文件“import-test01.py”,第16行,在
bar()
文件“import-test01.py”,第7行,条形图
logging.info('bar'))
UnboundLocalError:分配前引用的局部变量“logging”
显然,函数中的import语句隐藏了函数作用域中已经存在的同名变量,即使导入没有执行

这让人感觉违反直觉,而且不是蟒蛇式的。我试图找到一些关于这方面的信息或文档,但迄今为止没有多少成功。有人对这种行为有更多的信息/见解吗


感谢通过
import
语句,您在函数中引入了
logging
作为局部变量,并在初始化之前调用该局部变量

def bar():
    import logging.handlers
    print locals()

>>> foo()
{'logging': <module 'logging' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/logging/__init__.pyc'>}
def bar():
导入日志记录处理程序
打印本地文件()
>>>foo()
{'logging':}

您遇到的问题只是重申了python处理本地屏蔽全局的相同方式

为了理解它,
import foo
是(近似)语法糖:

foo = __import__("foo")
因此,您的代码是:

x = 1
def bar():
    print x
    if False:
        x = 2
由于名称
logging
显示在条内赋值语句的左侧,因此它被视为局部变量引用,因此python不会在该范围内查找同名的全局变量,即使设置它的行永远无法调用

处理全局变量的常见解决方法是:使用其他名称,如您所发现的,或者:

def bar():
    global logging
    logging.info('bar')
    if False:
        import logging.handlers

因此python不会认为
日志记录是本地的。

的确如此,但它只在执行import语句之后才在
locals()
中,这完全是意料之中的。我的问题是,“日志记录”不在import语句(不一定要执行)之前的
locals()
中,而是在
globals()
中,我仍然得到
UnboundLocalError
,就好像仍然是一个未定义的局部变量。哦,我明白了,我认为这是一个常识:Python在执行函数之前编译函数,并且该函数中提供了所有局部变量的元组。因此,当它试图将该变量放入这个元组时,它还没有->UnboundLocalErrorYeah,有了IfLoop的回答(关于导入与局部变量赋值等效),我现在明白你的意思了,谢谢。处理屏蔽问题的一种方法是在导入时使用“as”。。。。如果为False:将logging.handlers导入为handler@Stefaan这似乎是遵循以下规则的好理由:“导入总是放在文件的顶部,就在任何模块注释和docstring之后,模块全局变量和常量之前。”我知道,经常有违反规则的理由(风险由您自己承担)。
x = 1
def bar():
    print x
    if False:
        x = 2
def bar():
    global logging
    logging.info('bar')
    if False:
        import logging.handlers