如何避免因指针的类型提示循环依赖在python属性
问题描述:
考虑两个模块(在相同的文件夹中):如何避免因指针的类型提示循环依赖在python属性
首先,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))
然后pet.py
from .person import Person
class Pet:
def __init__(self, name: str, owner: Person):
self.name = name
self.owner = owner
由于循环依赖性,上面的代码将不起作用。你会得到一个错误:
ImportError: cannot import name 'Person'
的一些方法,使其工作:
- 保持类Person和宠物的定义在同一个文件。
- 与pet.owner属性做掉(这是有作为一种方便的指针)
- 不使用type-提示/注释,其中它会导致循环引用:
例如只需要:
class Pet:
def __init__(self, name: str, owner):
我在目前列出的所有选项中看到一些缺点。
还有别的办法吗? 一个,让我
- 分班放到不同的文件
- 利用类型的注释与指针如所示
或组合:是否有很好的理由,而不是遵循的解决方案之一我已经列出?
答
一些更多的学习之后,我意识到有做这种正确的方法:继承:
首先我定义的人,不[宠物]或在OP的方法。 然后,我定义了宠物,并拥有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))
的人需要参考宠物现在应该PetOwner和所有方法中定义的所有方法/在宠物使用人的属性,需要人来定义。如果需要使用仅存在于PetOwner中的Pet中的方法/属性,则新的Pet类子
例如应该定义OwnedPet。
当然,如果命名困扰我,我可以从Person和PetOwner分别更改为BasePerson和Person或类似的东西。
通常它可以帮助,而不是'从.person导入Person'从'导入模块'。导入人员“并使用长名字”person.Person“(对于pet.Pet也是如此)。这里已经给出了解释,不想复制它。 – VPfB
你能指出我对这个解释吗?我尝试了你的建议,但是我从pet.py文件中得到一个错误: AttributeError:module'demo。人'没有属性'人' 对我来说这是有道理的,因为在导入Person类期间,Pet类被导入*,因此,在导入Pet时,还没有导入的Person类。 – levraininjaneer
我记得M.Pieters的一个答案。这个问题是我的,答案解释了依赖模块内容和模块存在之间的区别。链接https://stackoverflow.com/questions/36137093/why-has-the-cyclical-import-issue-disappeared希望它可以帮助你,因为它帮助我。 – VPfB