【问题标题】:Python Import Statement and Recursion- need function available in module namespacePython 导入语句和递归 - 模块命名空间中可用的需要函数
【发布时间】:2013-07-20 12:03:09
【问题描述】:

我在 main.py 中有函数 foo()。在 main.py 中,我导入 create.py。但是 create.py 中有一个函数需要 main 中的 foo()。我无法将 main.py 导入 create.py,因为 main.py 出错了……我认为这是某种竞争条件。

如何使 foo() 在 create.py 命名空间中可用?将 foo() 设为一个模块并由 main.py 和 create.py 仅针对一个函数导入似乎效率低下。

【问题讨论】:

  • 伙计,开始导入 main.py,create.py 无限次。我敢打赌,为 foo() 创建一个额外的模块并通过 main.py 和 create.py 导入它是唯一的解决方案。

标签: python import module namespaces


【解决方案1】:

简单的答案是将 foo() 移至 foo.py 并从那里导入,或者将其移至 create.py 并将其从那里导入 main.py - 如果 main.py 中有需要移动的东西也。您的另一个选择是将 foo 从 main 传递到 create 作为需要它的函数参数。

【讨论】:

    【解决方案2】:

    只是一个简单的 hack,但这在一般情况下无济于事。

    在main.py中通过导入调用create.py。

    # in main.py
    if __name__ == '__main__':
        from create import *
    

    因此,当您通过python main.py 执行 main.py 时,这将导入 create,这将导入 create,并将再次导入 main,但是这一次,它将看到它正在被导入,因此 __name__ == '__main__' 将返回 False。所以循环导入链将停止。

    请记住,当您尝试在其他脚本中导入 main.py 时,它将不起作用,因为此时不会导入 create.py。

    所以要让这个东西工作,你必须执行main.py,你不能导入它。

    【讨论】:

      【解决方案3】:

      当您导入一个模块时,Python 的 import 机器会执行该模块的代码来填充它,但只会执行一次。如果您多次导入同一个模块,它会从sys.modules 缓存中获取。没有办法以无限导入循环结束。

      但是,Python 在执行代码之前将模块添加到 sys.modules,因此在执行整个模块之前不会完全填充它。因此,如果模块 A 导入模块 B,并且模块 B 再次导入模块 A,它将看到一个部分初始化的模块。这似乎是这里发生的事情; maincreate 完全填充之前导入它,因此当 create 尝试访问 main 中的某些内容时,它还不存在。

      一些解决方案:

      1. 如上所述,将共享代码移至单独的模块。导入只进行一次,Python 将编译后的字节码缓存在 PYC 文件中,因此成本并不高。
      2. 将所有代码移动到函数中,并在任何地方使用import name(没有from name import),并从脚本底部调用您的主函数。这样,所有模块都会在您执行任何其他操作之前完成导入。
      3. import create 语句移到您需要访问的函数下方,因此它是在执行create.py 中的代码之前定义的(这有点傻,但可以作为最后的手段)。

      【讨论】:

        猜你喜欢
        • 2019-01-08
        • 2019-03-14
        • 1970-01-01
        • 2017-07-15
        • 1970-01-01
        • 2014-01-26
        • 1970-01-01
        • 2023-03-19
        • 2017-12-20
        相关资源
        最近更新 更多