python - 使用公共常量模块导致循环导入
问题描述
我想constants
从两个不同模块的模块中导入常量,但出现以下错误:
Traceback (most recent call last):
File "C:\Temp\tmp\pycircular\pycircular\pycircular.py", line 2, in <module>
from my_classes.foo import Foo
File "C:\Temp\tmp\pycircular\pycircular\my_classes\foo.py", line 1, in <module>
from pycircular.constants import ANOTHER_CONSTANT
File "C:\Temp\tmp\pycircular\pycircular\pycircular.py", line 2, in <module>
from my_classes.foo import Foo
ImportError: cannot import name 'Foo' from partially initialized module 'my_classes.foo' (most likely due to a circular import) (C:\Temp\tmp\pycircular\pycircular\my_classes\foo.py)
我的项目结构如下:
|-constants.py
|-my_classes
| |-foo.py
| |-__init__.py
|-pycircular.py
|-__init__.py
# =============
# pycircular.py
# =============
from constants import SOME_CONSTANT
from my_classes.foo import Foo
def main():
print(SOME_CONSTANT)
my_foo = Foo()
my_foo.do_something()
if __name__ == "__main__":
main()
# =============
# foo.py
# =============
from pycircular.constants import ANOTHER_CONSTANT
class Foo:
def do_something(self):
print(ANOTHER_CONSTANT)
# =============
# constants.py
# =============
ANOTHER_CONSTANT = "ANOTHER"
SOME_CONSTANT = "CONSTANT"
我认为这与此处解决的问题相同https://stackoverflow.com/a/62303448/2021763。但我真的不明白为什么from my_classes.foo import Foo
inpycircular.py
被称为第二次。
更新:
在将包重命名pycircular
为它后,pycircular_pack
它在 PyCharm 中工作。但它只起作用,因为在 Pycharm 中该选项Add content roots to to PYTHONPATH
是自动设置的。
的输出sys.path
是['C:\\Temp\\tmp\\pycircular\\pycircular_pack', 'C:\\Temp\\tmp\\pycircular', 'C:\\Tools\\miniconda\\envs\\my_env\\python39.zip', 'C:\\Tools\\miniconda\\envs\\my_env\\DLLs', 'C:\\Tools\\miniconda\\envs\\my_env\\lib', 'C:\\Tools\\miniconda\\envs\\my_env', 'C:\\Tools\\miniconda\\envs\\my_env\\lib\\site-packages']
没有该选项,输出是['C:\\Temp\\tmp\\pycircular\\pycircular_pack', 'C:\\Tools\\miniconda\\envs\\my_env\\python39.zip', 'C:\\Tools\\miniconda\\envs\\my_env\\DLLs', 'C:\\Tools\\miniconda\\envs\\my_env\\lib', 'C:\\Tools\\miniconda\\envs\\my_env', 'C:\\Tools\\miniconda\\envs\\my_env\\lib\\site-packages']
如果没有这个选项,我只能让它与绝对导入一起使用。
# pycircular.py
from constants import SOME_CONSTANT
from my_classes.foo import Foo
...
# foo.py
from constants import ANOTHER_CONSTANT
解决方案
根据评论和编辑进行详细说明:
将包 pycircular 重命名为 pycircular_pack 后,它在 PyCharm 中工作。但它之所以有效,是因为在 Pycharm 中,自动设置了将内容根添加到 PYTHONPATH 选项。
您应该确保包目录未设置为内容根目录或源根目录。托管包目录的目录应设置为源根目录。
C:\Temp\tmp\pycircular # <- source root
|- pycircular_pack # <- not set as anything
| |- constants.py
| |- my_classes
| | |- foo.py
| | |- __init__.py
| |- pycircular.py
| |- __init__.py
|- other_file.py # <- for illustration's sake
现在您sys.path
将被设置为C:\Temp\tmp\pycircular
仅包含,并且只有一种方法可以从您的模块中导入内容。
即,
other_file.py
(包外)将能够将包用作pycircular_pack
pycircular_pack/*.py
可以通过以下任一方式引用pycircular_pack
包 中的模块- (例如)
from .constants import ...
(从当前包的相对导入),或 - (例如)
from pycircular_pack.constants import ...
(绝对进口)
- (例如)
pycircular_pack/my_classes/*.py
可以通过以下任一方式引用pycircular_pack
包 中的模块- (例如)
from ..constants import ...
(从父包的相对导入),或 - (例如)
from pycircular_pack.constants import ...
(绝对进口)
- (例如)
如果您的pycircular_pack
包将包含一个可运行的脚本,例如 CLI as pycircular_pack/cli.py
,那么在命令行上运行该脚本的正确方法是使用python -m pycircular_pack.cli
; 这让 Python 像我们在这里想要的那样设置了路径,在那里python pycircular_pack/cli.py
不会做正确的事情。
推荐阅读
- c# - 为什么我不能将图片框中的“一些”图像保存到数据库中?
- pycharm - 为什么我的新文件没有添加到 Pycharm 项目中
- xpath - Saxon PE 和 EE 从 format-date 返回不同的结果
- c# - 删除 AppData 中的 [eid]_[hash]
- app-store-connect - 是否有 Apple Store Connect API 用于获取应用的展示次数、产品浏览量、下载量?
- browser-automation - 如何检查 Flutter Web 应用程序中的元素。如何在 Flutter Web 应用程序中进行自动化测试
- uml - 部署图和硬件细节
- c - 为什么 ac 程序中的 fork 后 execv 比 printf 慢?
- python - Python中可以向ThreadPoolExecutor提交多少个任务
- smartcard - 香港ID芯片命令和响应APDU