簡體   English   中英

讓對象相互引用的pythonic方法是什么?

[英]What is the pythonic way to have objects that reference one another?

假設我有以下代碼。

class Person:
    def __init__(partner: Person)
       self.partner = partner

所以,基本上,我們有一個人的世界,每個人都有一個伙伴。 顯然,這種關系是相互的:如果 A 與 B 作為合作伙伴,那么 B 必須與 A 作為合作伙伴。

但是你如何讓這段代碼在實踐中發揮作用呢? 我什至如何實例化 A 或 B? 並且應該避免這樣的代碼,以免遇到遞歸問題? 什么是普遍做法?

您可以在實例化之后使用一種方法來創建 2 個鏈接,請注意,這是對另一個鏈接的引用,而不是副本

class Person:
    def __init__(self, name):
        self.name = name
        self.partner = None

    def set_partner(self, other: 'Person'):
        self.partner = other
        other.partner = self  

    def __str__(self):
        if self.partner:
            return self.name + "<>" + self.partner.name
        return self.name + " is alone"
a = Person("A")
b = Person("B")
print(a)  # A is alone
print(b)  # B is alone

a.set_partner(b)
print(a)  # A<>B
print(b)  # A<>B

您不能使用other.set_partner(self) ,因為那樣會一次又一次地再次調用該方法,從而導致 RecursionError

可能有比讓Person對象包含對partner的引用更好的方法來對此進行建模,但是如果您確實需要循環引用,則解決方案是在對象實例化后設置它們:

class Person:
    def __init__(self):
       self.partner = None


alice = Person()
bob = Person()
alice.partner = bob
bob.partner = alice

一種不涉及對象本身之間循環引用的方法可能是將關系存儲在其他地方:

from dataclasses import dataclass

@dataclass(frozen=True)
class Person:
    name: str

partners: dict[Person, Person] = {}

alice = Person("Alice")
bob = Person("Bob")

partners[alice] = bob
partners[bob] = alice

除了@azro 的答案,但現在它避免了單方面的夫婦。

class Person:
    def __init__(self, name):
        self.name = name
        self.partner = None

    def set_partner(self, other: 'Person'):
        if self.partner is not None:      # |this is new
            self.partner.partner = None   # |
        if other.partner is not None:     # |
            other.partner.partner = None  # |
        self.partner = other
        other.partner = self  

    def __str__(self):
        if self.partner:
            return self.name + "<>" + self.partner.name
        return self.name + " is alone"

a = Person("A")
b = Person("B")
c = Person("C")
print(a)  # A is alone

a.set_partner(b)
b.set_partner(c)
print(a)  # A is alone again
print(b)  # B<>C
print(c)  # C<>B

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM