2

考慮兩個模塊(在相同的文件夾中):如何避免因指針的類型提示循環依賴在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

回答

0

一些更多的學習之後,我意識到有做這種正確的方法:繼承:

首先我定義的人,不[寵物]或在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或類似的東西。