[英]Python circular import in custom package and __init__.py
I get ImportError: cannot import name 'Result' from partially initialized module 'libs.elastic_search_hunt' (most likely due to a circular import) error when I try to run tests.当我尝试运行测试时,我得到ImportError: cannot import name 'Result' from partial initialized module 'libs.elastic_search_hunt'(很可能是由于循环导入)错误。 But I does not see any circular imports in my code.
但是我在我的代码中没有看到任何循环导入。
I have a package, named elastic_search_hunt which contains 3 modules:我有一个名为elastic_search_hunt的 package,它包含 3 个模块:
And I also have __init__.py file with following text:而且我还有__init__.py文件,其中包含以下文本:
from libs.elastic_search_hunt.elastic_query import Query
from libs.elastic_search_hunt.search_processor import SearchProcessor
from libs.elastic_search_hunt.elastic_query_result import Result
__all__ = ['Query', 'SearchProcessor', 'Result'] # I guess it does not have any effect
elastic_query.py has only external imports. elastic_query.py只有外部导入。
elastic_query_result.py the same. elastic_query_result.py相同。
search_processor.py has those import: search_processor.py有这些导入:
from . import Query
from . import Result
Then I have a test file, which imports Query class:然后我有一个测试文件,它导入查询class:
from libs.elastic_search_hunt import Query
When I run tests, I get this errors:当我运行测试时,我得到这个错误:
test_query.py:2: in <module>
from libs.elastic_search_hunt import Query
..\src\libs\elastic_search_hunt\__init__.py:2: in <module>
from libs.elastic_search_hunt.search_processor import SearchProcessor
..\src\libs\elastic_search_hunt\search_processor.py:4: in <module>
from . import Result
E ImportError: cannot import name 'Result' from partially initialized module 'libs.elastic_search_hunt' (most likely due to a circular import)
But where is any circular import in my code?但是我的代码中的任何循环导入在哪里? I only can assume that when I import Query from tests, it also import search_processor from the __init__.py module which in turn loads Query one more time.
我只能假设当我从测试中导入Query时,它也会从__init__.py模块中导入search_processor ,这又会再次加载Query一次。 But the error is about Result in elastic_query_result module and I see only one import of Result .
但错误是关于elastic_query_result模块中的Result ,我只看到一个Result导入。
When i delete search_processor from __init__.py everything works fine.当我从__init__.py中删除 search_processor 时,一切正常。
I have read a lot of issues about circular imports, but all of them was quite obvious and does not touch the __init__.py .我已经阅读了很多关于循环导入的问题,但所有这些问题都很明显,并且没有触及__init__.py 。 What am I missing?
我错过了什么?
TL;DR : replace from. import Query
TL;DR :替换
from. import Query
from. import Query
with from.elastic_query import Query
使用
from.elastic_query import Query
from. import Query
Explanation:解释:
When you import something from libs.elastic_search_hunt
module it loads __init__.py
at first.当您从
libs.elastic_search_hunt
模块导入某些内容时,它首先会加载__init__.py
。 Since every module executes at first import __init__.py
also being executed.由于每个模块首先执行 import
__init__.py
也正在执行。
Then Python executes code from __init__.py
and at second line然后 Python 从
__init__.py
和第二行执行代码
from libs.elastic_search_hunt.search_processor import SearchProcessor
it imports search_processor.py
.它导入
search_processor.py
。 Since it's first import - file must be executed - therefore all your imports in that file must be executed right now as well:由于它是第一次导入 - 必须执行文件 - 因此您在该文件中的所有导入也必须立即执行:
As you mentioned you have the following imports in your file:正如您提到的,您的文件中有以下导入:
from . import Query
from . import Result
At this point you tell python to load libs.elastic_search_hunt
entire module and take Query, Result
from it.此时您告诉 python 加载
libs.elastic_search_hunt
整个模块并从中获取Query, Result
。 So Python does.所以 Python 可以。
It makes an attempt to load libs/elastic_search_hunt/__init__.py
but wait... it is still not loaded completely.它尝试加载
libs/elastic_search_hunt/__init__.py
但等等……它仍然没有完全加载。 So it must load it, but in order to load it properly it must firstly load search_processor
which requires elastic_search_hunt/__init__.py
to be loaded.... oh well, there's a loop.所以它必须加载它,但为了正确加载它必须首先加载需要加载
elastic_search_hunt/__init__.py
的search_processor
......哦,好吧,有一个循环。
So in order to avoid such behaviour you should explicitly say from which module exactly you wish to load Query
and Result
, therefore change因此,为了避免这种行为,您应该明确说明您希望从哪个模块加载
Query
和Result
,因此更改
from . import Query
from . import Result
to至
from .elastic_query import Query
from .elastic_query_result import Result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.