这可以按预期工作
def outer_func():
from time import *
print time()
outer_func()
我可以在上下文中定义嵌套函数,并从其他嵌套函数中调用它们:
def outer_func():
def time():
return '123456'
def inner_func():
print time()
inner_func()
outer_func()
我甚至可以导入个别功能:
def outer_func():
from time import time
def inner_func():
print time()
inner_func()
outer_func()
然而,这会引发SyntaxError: import * is not allowed in function 'outer_func' because it contains a nested function with free variables
:
def outer_func():
from time import *
def inner_func():
print time()
inner_func()
outer_func()
我知道这不是最佳做法,但为什么不起作用?
答案 0 :(得分:22)
编译器无法知道时间模块是否导出名为time
的对象。
嵌套函数的自由变量在编译时与闭包单元相关联。闭包单元本身指向编译代码中定义的(局部)变量,而不是根本没有绑定的全局变量。见python data model;函数通过func_globals
属性引用它们的全局变量,func_closure
属性包含一系列闭包单元格(或None
)。
因此,您不能在嵌套作用域中使用动态导入语句。
为什么嵌套函数需要闭包单元呢?因为在函数本身完成时需要一种机制来引用局部函数变量:
def foo(spam):
def bar():
return spam
return bar
afunc = foo('eggs')
通过调用foo()
,我获得了一个引用范围变量的嵌套函数,编译器需要为解释器创建必要的引用,以便能够再次检索该范围变量。因此,细胞和它们受到限制。