困惑为什么要导入os; os.environ['a'] = 'x'; import os.path 引发 UnboundLocalError
Confused why import os; os.environ['a'] = 'x'; import os.path raises UnboundLocalError
有人可以解释为什么会发生以下情况吗?我看了一下 Should I use `import os.path` or `import os`?,它提供了很多信息,大致相似,但并没有真正为我阐明。
如果我把import os.path
注释掉或者直接在import os
后面加上就没有错误了。
$ python -V
Python 2.7.2
$ cat min.py
import os
def main():
os.environ['blah'] = 'bloo'
import os.path
if __name__ == '__main__':
main()
$ python min.py
Traceback (most recent call last):
File "min.py", line 9, in <module>
main()
File "min.py", line 4, in main
os.environ['blah'] = 'bloo'
UnboundLocalError: local variable 'os' referenced before assignment
$
发生这种情况是因为您在导入库 'os' 之前尝试使用它。
你可以做到
def main():
import os
#now you can use os.environment
os.environ['blah'] = 'bloo'
#you don't need to import os.path as os is already imported
if __name__ == '__main__':
main()
因为导入也是赋值。如果您在 main 方法中执行 import os.path
,您将 os
设为 local 名称,并且 Python 不会在全局范围内查找查看您已经导入的 os
。
# assigns 'os' to global namespace
import os
def main():
os.environ['blah'] = 'bloo' # <== which 'os'? python assumes local
# assigns 'os' to local namespace
import os.path
import
做了两件事。首先,它创建一个模块对象。其次,它为新创建的模块对象命名。给某物命名是赋值,因此出现错误消息“UnboundLocalError: local variable 'os' referenced before assignment
”。
Python 有关于名称可见性和何时可以引用的规则。规则之一是函数中不能有歧义,即你指的是局部名称还是全局名称。如果在函数内部的任何位置创建了与全局名称相同的局部名称,Python 假定函数内部对该名称的所有引用都引用局部名称(除非您特别说明)。
三个可能的修复。
删除本地导入:
import os
def main():
os.environ['blah'] = 'bloo'
删除全局导入并将局部导入移至函数顶部
def main():
import os.path
os.environ['blah'] = 'bloo'
在函数开头声明 os
全局,以便第一个引用使用全局:
import os
def main():
global os
os.environ['blah'] = 'bloo'
import os.path
关于导入的注意事项。
# has the same effect as 'import module'
# creates a reference named 'module'
import module.submodule
# imports submodule and creates a reference to it named 'submodule'
from module import submodule
# imports submodule and creates a reference to it named 'x'
import module.submodule as x
有人可以解释为什么会发生以下情况吗?我看了一下 Should I use `import os.path` or `import os`?,它提供了很多信息,大致相似,但并没有真正为我阐明。
如果我把import os.path
注释掉或者直接在import os
后面加上就没有错误了。
$ python -V
Python 2.7.2
$ cat min.py
import os
def main():
os.environ['blah'] = 'bloo'
import os.path
if __name__ == '__main__':
main()
$ python min.py
Traceback (most recent call last):
File "min.py", line 9, in <module>
main()
File "min.py", line 4, in main
os.environ['blah'] = 'bloo'
UnboundLocalError: local variable 'os' referenced before assignment
$
发生这种情况是因为您在导入库 'os' 之前尝试使用它。 你可以做到
def main():
import os
#now you can use os.environment
os.environ['blah'] = 'bloo'
#you don't need to import os.path as os is already imported
if __name__ == '__main__':
main()
因为导入也是赋值。如果您在 main 方法中执行 import os.path
,您将 os
设为 local 名称,并且 Python 不会在全局范围内查找查看您已经导入的 os
。
# assigns 'os' to global namespace
import os
def main():
os.environ['blah'] = 'bloo' # <== which 'os'? python assumes local
# assigns 'os' to local namespace
import os.path
import
做了两件事。首先,它创建一个模块对象。其次,它为新创建的模块对象命名。给某物命名是赋值,因此出现错误消息“UnboundLocalError: local variable 'os' referenced before assignment
”。
Python 有关于名称可见性和何时可以引用的规则。规则之一是函数中不能有歧义,即你指的是局部名称还是全局名称。如果在函数内部的任何位置创建了与全局名称相同的局部名称,Python 假定函数内部对该名称的所有引用都引用局部名称(除非您特别说明)。
三个可能的修复。
删除本地导入:
import os
def main():
os.environ['blah'] = 'bloo'
删除全局导入并将局部导入移至函数顶部
def main():
import os.path
os.environ['blah'] = 'bloo'
在函数开头声明 os
全局,以便第一个引用使用全局:
import os
def main():
global os
os.environ['blah'] = 'bloo'
import os.path
关于导入的注意事项。
# has the same effect as 'import module'
# creates a reference named 'module'
import module.submodule
# imports submodule and creates a reference to it named 'submodule'
from module import submodule
# imports submodule and creates a reference to it named 'x'
import module.submodule as x