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

Python 为什么不能在数据结构中导入函数名,python,function,python-import,nameerror,Python,Function,Python Import,Nameerror,我有一个函数和一个字典,其中包含对该函数的引用 def func1(): print('blah') dict1 = {'func1': func1} 如果我按照给定的顺序将它们粘贴到python解释器中,所有这些都可以正常工作 `>>> def func1(): print('blah') ... >>> func1 <function func1 at 0x7f8939d77730> >>> func1() blah

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

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

`
然后将其输入解释器:

>>> 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
>>> 
这是怎么回事?

在dictfile.py上下文的范围内没有定义func1

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

从python中:

因此,模块的作者可以在模块中使用全局变量 无需担心与用户的全局 变量

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

为了能够加载引用该函数的字典,必须在该函数所在的文件的作用域中定义该函数

由于dictfile.py文件不知道有关解释器当前状态的任何信息,因此没有将您的状态导入到该文件中,并且我不确定这是否可行,因此它无法找到该函数的引用

def func1(): print('blah')

dict1 = {'func1': func1}
根据Python的说法

每个模块都有自己的专用符号表,用作 由模块中定义的所有函数生成的全局符号表。因此 模块作者可以在模块中使用全局变量,而无需 担心与用户的全局变量发生意外冲突。在…上 另一方面,如果你知道你在做什么,你可以触碰 模块的全局变量,其符号与用于引用其 函数,modname.itemname

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

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

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

从python中:

因此,模块的作者可以在模块中使用全局变量 无需担心与用户的全局 变量

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

为了能够加载引用该函数的字典,必须在该函数所在的文件的作用域中定义该函数

由于dictfile.py文件不知道有关解释器当前状态的任何信息,因此没有将您的状态导入到该文件中,并且我不确定这是否可行,因此它无法找到该函数的引用

def func1(): print('blah')

dict1 = {'func1': func1}
根据Python的说法

每个模块都有自己的专用符号表,用作 由模块中定义的所有函数生成的全局符号表。因此 模块作者可以在模块中使用全局变量,而无需 担心与用户的全局变量发生意外冲突。在…上 另一方面,如果你知道你在做什么,你可以触碰 模块的全局变量,其符号与用于引用其 函数,modname.itemname


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

每个模块定义一个名称空间,因此模块中的全局变量实际上是在该模块的范围内;另一个模块可以访问它们,但它需要通过定义名称的模块来访问它们

在交互式会话中运行时,您创建的对象将添加到一个名为_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
在现实世界的程序中,应该避免这样的循环依赖关系。但是,从一个模块导入函数,将它们组装到另一个模块的数据结构中,然后使用第三个模块的数据结构仍然是有用的

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

每个模块都定义了一个名称空间,因此模块中的全局变量实际上被限定在该模块的范围内;另一个模块可以访问它们,但它需要通过定义名称的模块来访问它们

在交互式会话中运行时,您创建的对象将添加到一个名为_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
在现实世界的程序中,应该避免这样的循环依赖关系。但是,从一个模块导入函数,将它们组装到另一个模块的数据结构中,然后使用第三个模块的数据结构仍然是有用的


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

func1引用在运行时存在,您不能从文件中保存或加载它。请使用getattrmodule之类的工具,func1中,您为dict.Raghava的注释赋值,该注释有用且信息丰富,听起来像是一个答案。请你详细说明一下好吗?这个网站有点做作:当你的一个回复让人们改变主意时,人们总是删除他们的评论。我对你有用的困惑表达作了进一步澄清。func1引用在运行时存在,您无法从文件中保存或加载它。请使用getattrmodule、func1之类的工具,将值赋给dict。Raghava的注释有用且信息丰富,听起来像是一个答案。请你详细说明一下好吗?这个网站有点做作:当你的一个回复让人们改变主意时,人们总是删除他们的评论。我已经补充了进一步的澄清,以回应你的困惑。谢谢。是的,情况似乎确实如此。但为什么会这样呢?这似乎违反直觉。我在我的范围内定义了函数。然后我在该范围内调用一个声明,其中包含对该函数的引用。既然我将该声明引入我的范围,那么我不是在包含它所引用的对象的范围内进行声明吗?delcaration肯定不是在哑文件中制作的。它是在我导入文件时生成的,当我导入文件时,它所需的函数在我的作用域中定义。@markling请参阅更新的答案;添加了我在Python文档中找到的更多细节,这应该有助于解释它。谢谢,@Pedro von Hertwig。我编辑了你的答案,详细阐述了其中的一部分,我觉得这对我理解这个问题很有帮助。谢谢。是的,情况似乎确实如此。但为什么会这样呢?这似乎违反直觉。我在我的范围内定义了函数。然后我在该范围内调用一个声明,其中包含对该函数的引用。既然我将该声明引入我的范围,那么我不是在包含它所引用的对象的范围内进行声明吗?delcaration肯定不是在哑文件中制作的。它是在我导入文件时生成的,当我导入文件时,它所需的函数在我的作用域中定义。@markling请参阅更新的答案;添加了我在Python文档中找到的更多细节,这应该有助于解释它。谢谢,@Pedro von Hertwig。我编辑了你的回答,详细阐述了其中我认为最有助于我理解问题的那一部分。是的,这种循环依赖正是我所创造的,并且将立即放弃,现在把问题放在一边,以便将来考虑必须做些什么,以不同的方式实现相同的目的。谢谢你。是的,这种狭隘的依赖正是我所创造的,我将立即放弃,现在把问题放在一边,供将来考虑,究竟应该做些什么,以不同的方式达到相同的目的。非常感谢。