简体   繁体   English

如何交叉导入子目录中的模块,以便它们既可以作为子模块又可以独立运行?

[英]How to cross-import modules in subdirectory so they work as sub-module and as a stand-alone?

I have a Python module that normally works as a stand-alone. 我有一个Python模块,该模块通常可以独立运行。

file1.py
file2.py
file3.py

However, I also want it to be part of a different project, in which the module is placed in a separate subdirectory. 但是,我也希望它成为另一个项目的一部分,在该项目中,模块位于单独的子目录中。

__init.py__
build.py
└── compiler
    └── __init__.py
    └── file1.py
    └── file2.py
    └── file3.py

Since the module scripts use plenty of cross-imports, this is not possible. 由于模块脚本使用了大量交叉导入,因此这是不可能的。 Once placed in a subdirectory, the imports no longer find the respective files because it looks in the top directory only. 一旦放置在子目录中,导入将不再找到相应的文件,因为它们仅在顶部目录中查找。

To remedy the problem, I tried various things. 为了解决这个问题,我尝试了各种方法。 I appended the subdirectory as an additional path in the top-most build.py script. 我在最顶层的build.py脚本中将子目录附加为附加路径。

sys.path.append('compiler')

It did not solve the problem. 它没有解决问题。 Cross-imports are still not working. 交叉进口仍无法正常工作。

I also tried relative imports but that breaks the stand-alone version of the module. 我也尝试了相对导入,但这破坏了模块的独立版本。 So, I tried exception handling to catch them 因此,我尝试了异常处理来捕获它们

try:
    from file1 import TestClass
except ImportError:
    from .file1 import TestClass

That did not work either and resulted, despite my best efforts in ImportError: attempted relative import with no known parent package errors. 尽管我在ImportError: attempted relative import with no known parent package尽了最大的努力,但这也不起作用,并且导致了结果ImportError: attempted relative import with no known parent package错误。

I also tried all sorts of variations of these things, but none of it worked. 我还尝试了这些方法的各种变体,但没有一个起作用。

I know it has to be possible to do something like this and I am surprised that this is so hard to do. 我知道一定可以做这样的事情,我很惊讶这样做很难。 My Internet searches all came back with the same suggestions—the ones I outlined above, none of which worked in my case, particularly because they do not take into account the ability to run code as a stand-alone and as a sub-module. 我的Internet搜索都返回了相同的建议-我在上面概述了这些建议,但在我的情况下这些建议都不起作用,特别是因为它们没有考虑将代码作为独立模块和子模块运行的能力。

I can't be the first person trying to write a module that can be used as a stand-alone package or as a sub-module in other projects. 我不能成为尝试编写可用作独立程序包或用作其他项目中的子模块的模块的第一人。 What am I missing here? 我在这里想念什么?

Relative imports, as the error tells you, require a parent package. 如错误所示,相对导入需要父程序包。 Think of .file1 as shorthand for <this_module>.file1 . .file1视为<this_module>.file1简写。 If there is no <this_module> , you can't ask it for file1 . 如果没有<this_module> ,则不能要求它提供file1 In order to properly use relative imports you'll have to make a wrapper project to contain the shared module so it can be properly namespaced. 为了正确使用相对导入,您必须创建一个包装项目以包含共享模块,以便可以对其进行正确的命名空间。

So your standalone module will instead look like this, matching the consumer: 因此,您的独立模块将如下所示,与使用者匹配:

__init.py__
standalone.py
└── compiler
    └── __init__.py
    └── file1.py
    └── file2.py
    └── file3.py

The other option is to make your shared module truly installable with a setup.py or pyproject.toml or whatever your favorite method is. 另一个选择是使用setup.pypyproject.toml或您喜欢的任何方法使共享模块真正可安装。 Then you install it in the consuming project instead of directly including it. 然后,将其安装在使用项目中,而不是直接包含它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM