Python导入语句和递归-需要模块命名空间中可用的函数

Python导入语句和递归-需要模块命名空间中可用的函数,python,import,module,namespaces,Python,Import,Module,Namespaces,我在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为一个函数导入似乎效率低下 简单的答案是将foo()移动到foo.py并从那里导入,或者将其移动到create.py并从那里导入main.py-如

我在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为一个函数导入似乎效率低下

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

只是一个简单的hack,但这在一般情况下不会有帮助

导入main.py中的create.py,如果导入调用的是而不是

# in main.py
if __name__ == '__main__':
    from create import *
因此,当您通过
python main.py执行main.py时,这将导入create,这将导入create,并且它将再次导入main,但这一次,它将看到它正在被导入,因此
\uu name\uuu=='\uuuuu main\uuu'
将返回
False。因此,进口的循环链将停止

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


因此,要使它工作,您必须执行main.py,您不能导入它。

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

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

一些解决方案:

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

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