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

时间:2012-11-19 15:06:28

标签: python python-2.x

这可以按预期工作

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()

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

1 个答案:

答案 0 :(得分:22)

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

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

因此,您不能在嵌套作用域中使用动态导入语句。

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

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

afunc = foo('eggs')

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