如何避免因指针的类型提示循环依赖在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' 

的一些方法,使其工作:

  1. 保持类Person和宠物的定义在同一个文件。
  2. 与pet.owner属性做掉(这是有作为一种方便的指针)
  3. 不使用type-提示/注释,其中它会导致循环引用:

例如只需要:

class Pet: 
    def __init__(self, name: str, owner): 

我在目前列出的所有选项中看到一些缺点。

还有别的办法吗? 一个,让我

  • 分班放到不同的文件
  • 利用类型的注释与指针如所示

或组合:是否有很好的理由,而不是遵循的解决方案之一我已经列出?

+0

通常它可以帮助,而不是'从.person导入Person'从'导入模块'。导入人员“并使用长名字”person.Person“(对于pet.Pet也是如此)。这里已经给出了解释,不想复制它。 – VPfB

+0

你能指出我对这个解释吗?我尝试了你的建议,但是我从pet.py文件中得到一个错误: AttributeError:module'demo。人'没有属性'人' 对我来说这是有道理的,因为在导入Person类期间,Pet类被导入*,因此,在导入Pet时,还没有导入的Person类。 – levraininjaneer

+0

我记得M.Pieters的一个答案。这个问题是我的,答案解释了依赖模块内容和模块存在之间的区别。链接https://stackoverflow.com/questions/36137093/why-has-the-cyclical-import-issue-disappeared希望它可以帮助你,因为它帮助我。 – VPfB

一些更多的学习之后,我意识到有做这种正确的方法:继承:

首先我定义的人,不[宠物]或在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或类似的东西。