为什么我不能在函数中使用`import*`?

Wil*_*hes 15 python python-2.x

这按预期工作

def outer_func():
    from time import *

    print time()

outer_func()
Run Code Online (Sandbox Code Playgroud)

我可以在上下文中定义嵌套函数,并从其他嵌套函数中调用它们:

def outer_func():
    def time():
        return '123456'

    def inner_func():
        print time()

    inner_func()

outer_func()
Run Code Online (Sandbox Code Playgroud)

我甚至可以导入个别功能:

def outer_func():
    from time import time

    def inner_func():
        print time()

    inner_func()

outer_func()
Run Code Online (Sandbox Code Playgroud)

但是,这会引发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()
Run Code Online (Sandbox Code Playgroud)

我知道这不是最佳做法,但为什么不起作用?

Mar*_*ers 22

编译器无法知道时间模块是否导出了名为的对象time.

嵌套函数的自由变量在编译时与闭包单元相关联.闭包单元本身指向编译代码中定义的(局部)变量,而不是根本没有绑定的全局变量.参见python数据模型 ; 函数通过func_globals属性引用它们的全局变量,该func_closure属性包含一系列闭包单元格(或None).

因此,您不能在嵌套范围中使用动态导入语句.

为什么嵌套函数需要闭包单元呢?因为在函数本身完成时需要一种机制来引用局部函数变量:

def foo(spam):
    def bar():
        return spam
    return bar

afunc = foo('eggs')
Run Code Online (Sandbox Code Playgroud)

通过调用foo()我获得了一个引用范围变量的嵌套函数,编译器需要为解释器创建必要的引用,以便能够再次检索该范围变量.因此,细胞和它们受到限制.