代码之家  ›  专栏  ›  技术社区  ›  markling

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

  •  1
  • markling  · 技术社区  · 7 年前

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

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

    这是怎么回事?

    2 回复  |  直到 7 年前
        1
  •  3
  •   markling    7 年前

    func1 在您的 dictfile.py 上下文

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

    来自python docs :

    因此,模块的作者可以在模块中使用全局变量 无需担心与全球用户发生意外冲突 变量。

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

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

    dictfile。py公司 文件不知道解释器的当前状态(您的状态没有导入到文件中,我不确定这是否可能),它找不到函数的引用。

    根据Python 文档 ,

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

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

        2
  •  3
  •   Daniel Pryden    7 年前

    每个模块都定义了一个名称空间,因此模块中的“全局”变量实际上是该模块的作用域;另一个模块可以访问它们,但需要通过定义名称的模块进行访问。

    在交互式会话中运行时,您创建的对象将添加到一个名为 __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
    

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

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