lev*_*eer 6 python annotations circular-dependency type-hinting cross-reference
考虑两个模块(在同一文件夹中):
首先,person.py
from typing import List
from .pet import Pet
class Person:
def __init__(self, name: str):
self.name = name
self.pets = [] # type: List[Pet]
def adopt_a_pet(self, pet_name: str):
self.pets.append(Pet(pet_name))
Run Code Online (Sandbox Code Playgroud)
然后是pet.py
from .person import Person
class Pet:
def __init__(self, name: str, owner: Person):
self.name = name
self.owner = owner
Run Code Online (Sandbox Code Playgroud)
由于循环依赖,上述代码无法正常工作。您会得到一个错误:
ImportError: cannot import name 'Person'
Run Code Online (Sandbox Code Playgroud)
使其工作的一些方法:
例如:
class Pet:
def __init__(self, name: str, owner):
Run Code Online (Sandbox Code Playgroud)
到目前为止,我列出的所有选项中都有一些缺点。
还有另一种方法吗?一个让我能够
或者:是否有充分的理由改而采用我已经列出的解决方案之一?
Gor*_*don 10
我最近遇到了类似的问题,并通过使用以下方法解决了它:
import typing
if typing.TYPE_CHECKING:
from .person import Person
class Pet:
def __init__(self, name: str, owner: 'Person'):
self.name = name
self.owner = owner
Run Code Online (Sandbox Code Playgroud)
有所述的第二溶液这里,这需要Python> = 3.7 && <3.10。
from __future__ import annotations # <-- Additional import.
import typing
if typing.TYPE_CHECKING:
from .person import Person
class Pet:
def __init__(self, name: str, owner: Person): # <-- No more quotes.
self.name = name
self.owner = owner
Run Code Online (Sandbox Code Playgroud)
从 Python 3.10 开始,__future__将不再需要导入。
经过更多学习后,我意识到有一种正确的方法可以做到这一点:继承:
首先,我定义 Person,不带 [pets] 或 OP 中的方法。然后我定义 Pets,并拥有 Person 类的所有者。然后我定义
from typing import List
from .person import Person
from .pet import Pet
class PetOwner(Person):
def __init__(self, name: str):
super().__init__(name)
self.pets = [] # type: List[Pet]
def adopt_a_pet(self, pet_name: str):
self.pets.append(Pet(pet_name))
Run Code Online (Sandbox Code Playgroud)
Person 中需要引用 Pet 的所有方法现在都应该在 PetOwner 中定义,并且 Pet 中使用的 Person 的所有方法/属性都需要在 Person 中定义。如果需要使用 Pet 中仅存在于 PetOwner 中的方法/属性,则应定义 Pet 的新子类,例如 OwnedPet。
当然,如果命名令我烦恼,我可以将 Person 和 PetOwner 分别更改为 BasePerson 和 Person 或类似的名称。
| 归档时间: |
|
| 查看次数: |
627 次 |
| 最近记录: |