如何允许 Python3.5+ 中的相对循环导入仅用于数据类类型检查?
How to allow relative circular imports in Python3.5+ used only for dataclass type checks?
我的文件结构如下:
├── test_package
│ ├── __init__.py
│ └── models
│ ├── __init__.py
│ ├── a.py
│ └── b.py
以及以下文件内容:
# a.py
from .b import B
from dataclasses import dataclass
@dataclass
class A:
b: B
# b.py
from .a import A
from dataclasses import dataclass
@dataclass
class B:
a: A
尝试导入包 a 时,出现以下错误。
: import test_package.models.a
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-e8165f4eb507> in <module>
----> 1 import test_package.models.a
/.../test_package/models/a.py in <module>
----> 1 from .b import B
2 from dataclasses import dataclass
3
4 @dataclass
5 class A:
/.../test_package/models/b.py in <module>
----> 1 from .a import A
2 from dataclasses import dataclass
3
4 @dataclass
5 class B:
ImportError: cannot import name 'A' from 'test_package.models.a'
根据 Python3.5 change log,"Circular imports involving relative imports are now supported. (Contributed by Brett Cannon and Antoine Pitrou in bpo-17636.)" 我如何使这个相对循环导入工作?
请注意,我只需进行这些导入即可进行类型检查。
编辑:
作为对评论中@juanpa.arrivillaga 的回复,这里是 Python 2.7 发生相同错误的示例。除非我误解了某些东西,否则源文件似乎正在被找到并被执行。
$ cat a.py
from b import b_func
def a_func():
return "Hi"
$ cat b.py
from a import b_func
def b_func():
return "Hi"
>>> import a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 1, in <module>
from b import b_func
File "b.py", line 1, in <module>
from a import b_func
ImportError: cannot import name b_func
"When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later." 例如,
@dataclass
class A:
b: 'B'
@dataclass
class B:
a: A
>>> A.__annotations__ # This is what the type checker uses
{'b': 'B'}
有关详细信息,请参阅 https://www.python.org/dev/peps/pep-0484/#forward-references。
请注意,这不是我提出的问题的答案,但这是我希望得到的答案。所以我发布了这个答案,以防有人和我走同样的路。
我的文件结构如下:
├── test_package
│ ├── __init__.py
│ └── models
│ ├── __init__.py
│ ├── a.py
│ └── b.py
以及以下文件内容:
# a.py
from .b import B
from dataclasses import dataclass
@dataclass
class A:
b: B
# b.py
from .a import A
from dataclasses import dataclass
@dataclass
class B:
a: A
尝试导入包 a 时,出现以下错误。
: import test_package.models.a
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-e8165f4eb507> in <module>
----> 1 import test_package.models.a
/.../test_package/models/a.py in <module>
----> 1 from .b import B
2 from dataclasses import dataclass
3
4 @dataclass
5 class A:
/.../test_package/models/b.py in <module>
----> 1 from .a import A
2 from dataclasses import dataclass
3
4 @dataclass
5 class B:
ImportError: cannot import name 'A' from 'test_package.models.a'
根据 Python3.5 change log,"Circular imports involving relative imports are now supported. (Contributed by Brett Cannon and Antoine Pitrou in bpo-17636.)" 我如何使这个相对循环导入工作?
请注意,我只需进行这些导入即可进行类型检查。
编辑:
作为对评论中@juanpa.arrivillaga 的回复,这里是 Python 2.7 发生相同错误的示例。除非我误解了某些东西,否则源文件似乎正在被找到并被执行。
$ cat a.py
from b import b_func
def a_func():
return "Hi"
$ cat b.py
from a import b_func
def b_func():
return "Hi"
>>> import a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 1, in <module>
from b import b_func
File "b.py", line 1, in <module>
from a import b_func
ImportError: cannot import name b_func
"When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later." 例如,
@dataclass
class A:
b: 'B'
@dataclass
class B:
a: A
>>> A.__annotations__ # This is what the type checker uses
{'b': 'B'}
有关详细信息,请参阅 https://www.python.org/dev/peps/pep-0484/#forward-references。
请注意,这不是我提出的问题的答案,但这是我希望得到的答案。所以我发布了这个答案,以防有人和我走同样的路。