从主(导入)文件中获取函数?

时间:2017-03-06 22:11:29

标签: python python-2.7 python-import

假设我有一个非常长的脚本。(在我的情况下,长达1000多行)所以我把它分成了一些文件:

main.py #the file i execute
foo1.py #a file my main.py imports
foo2.py #a file imported by foo1.py

(注意:main.py导入多个文件,而不仅仅是一个) Foo1.py拥有Tkinter以及与之相关的东西,而Foo2.py拥有一个巨大的对象类,其中包含与所述类相关的函数。

我的问题如下:

  • Foo1导入Foo2
  • Foo2运行一个从Foo1调用另一个函数的函数
  • Foo2引发'全局名称'未定义'错误

而且我也无法将该函数导入Foo2,因为Foo1已经拥有它并且会引发导入错误。

1 个答案:

答案 0 :(得分:1)

当两个模块相互导入时,您需要记住一些事项,以便在需要之前定义所有内容。

首先考虑导入机制:

  • 首次导入模块时,会将一个条目添加到sys.modules并且定义文件开始执行(暂停执行导入程序)
  • 后续导入只会使用sys.modules中的条目 - 文件是否已完成执行

那么先说加载模块A,导入模块B然后导入模块A,当发生这种情况时执行如下:

  1. A首次从其他地方导入,A已添加到sys.modules
  2. 执行
  3. A以导入B
  4. B已添加到sys.modules
  5. 执行
  6. B
    • 导入A时,部分加载的模块来自sys.modules
    • B在恢复之前完全运行
  7. A继续执行,可以访问完整模块B
  8. * 1所以from A import x只有在x A之前import B定义import A时才有效,只需使用def即可获得模块对象在文件执行时更新,因此虽然在导入后它可能没有所有定义,但是当文件有机会完成执行时。

    所以解决这个问题的最简单方法是首先不要依赖导入来执行模块 - 这意味着循环导入的所有用法都在var obj = new Derived { Licensed = () => true; }; obj.Enabled = () => obj.Licensed() && true; 块内,而不是从模块级别调用执行。