为什么我不能在数据结构中导入函数名

Why can I not import a function name within a data structure

我有一个函数和一个包含对该函数的引用的字典。

def func1(): print('blah')

dict1 = {'func1': func1}

如果我按照给定的顺序将它们粘贴到 python 解释器中,一切正常。

`>>> def func1(): print('blah')
... 

>>> func1
<function func1 at 0x7f8939d77730>

>>> func1()
blah

>>> dict1 = {'func1': func1}
>>> dict1['func1']()
blah

`

但是,如果我从文件中导入 dict1,解释器会说 func1 未定义,即使它已定义。

因此,文件 'dictfile.py' 包含一行文本:

dict1 = {'func1': func1}

然后这个进入解释器:

>>> def func1(): print('blah')
... 
>>> func1()
blah

>>> from dictfile import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/../dictfile.py", line 1, in <module>
    dict1 = {'func1': func1}
NameError: name 'func1' is not defined
>>> 

这是怎么回事?

func1 未在您的 dictfile.py 上下文范围内定义。

'func1' 的全局范围仅限于它自己定义的范围。这样它就可以作为一个独立的模块运行。也就是说,它可以像模块应该运行的那样运行:因此它可以被任何其他模块导入和运行。这样做是为了避免不同模块在其全局定义中对不同事物使用相同名称时发生冲突。

来自python docs:

Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables.

通过使用 import 语句加载文件,您可以使它成为一个模块。然后您不能期望该模块获取您导入它的范围。它自己的范围仍然是不同的。它的完整性受到保护。如果它自己没有定义它们,它必须自己导入它使用的任何定义。

为了能够加载引用函数的字典,函数必须在它所在的范围(文件)中定义。

因为 dictfile.py 文件对你的解释器的当前状态一无所知(你的状态没有导入到文件中,我不确定这是否可能),它找不到函数引用。

根据 Python docs,

Each module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. Thus, the author of a module can use global variables in the module without worrying about accidental clashes with a user’s global variables. On the other hand, if you know what you are doing you can touch a module’s global variables with the same notation used to refer to its functions, modname.itemname.

为了在模块(文件)范围内访问您的函数,您需要导入交互式解释器的 "module",我认为这是不可能的。

每个模块都定义了一个命名空间,因此 "global" 模块中的变量实际上是针对该模块的;另一个模块可以访问它们,但它需要通过定义名称的模块来访问。

当 运行 在交互式会话中时,您创建的对象将添加到名为 __main__ 的特殊模块中。如果需要,另一个模块可以从中导入东西,但我不推荐它。

举个例子,仅供学习:

$ cat dictfile.py
from __main__ import func1
dict1 = {'func1': func1}

$ python
Python 2.7.10 (default, Jul 30 2016, 19:40:32) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def func1(): print('blah')
...
>>> from dictfile import dict1
>>> dict1
{'func1': <function func1 at 0x102735c08>}
>>> dict1['func1']()
blah

在真实的程序中,你应该避免像这样的循环依赖。但是从一个模块中导入函数,assemble 将它们导入另一个模块中的数据结构,然后使用第三个模块中的数据结构仍然很有用。

关于程序各部分之间依赖关系的一个很好的经验法则:实现应该只依赖于抽象,而抽象应该只依赖于其他抽象。