简体   繁体   English

让对象相互引用的pythonic方法是什么?

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

Let's say I have the following code.假设我有以下代码。

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

So, basically, we have a world of persons, and every person has one partner.所以,基本上,我们有一个人的世界,每个人都有一个伙伴。 Obviously this relationship is mutual: if person A has person B as a partner, then person B must have person A as a partner.显然,这种关系是相互的:如果 A 与 B 作为合作伙伴,那么 B 必须与 A 作为合作伙伴。

But how would you make this code work in practice?但是你如何让这段代码在实践中发挥作用呢? How would I even instantiate A or B?我什至如何实例化 A 或 B? And should code like this be avoided so as one does not run into recursive issues?并且应该避免这样的代码,以免遇到递归问题? What is common practice?什么是普遍做法?

You can use a method, after instanciation, that would create the 2 links, note that this a reference to the other not a copy您可以在实例化之后使用一种方法来创建 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

You can't use other.set_partner(self) because that would then call again the method again and again, leading to a RecursionError您不能使用other.set_partner(self) ,因为那样会一次又一次地再次调用该方法,从而导致 RecursionError

There may be better ways to model this than having the Person object contain a reference to partner , but if you do need circular references, the solution is to set them up after the objects have been instantiated:可能有比让Person对象包含对partner的引用更好的方法来对此进行建模,但是如果您确实需要循环引用,则解决方案是在对象实例化后设置它们:

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


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

A way to do this that didn't involve circular references between the objects themselves might be to store the relationships somewhere else:一种不涉及对象本身之间循环引用的方法可能是将关系存储在其他地方:

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

Addition to @azro's answer, but now it avoids having one-sided couples.除了@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.

相关问题 将“兄弟”模块相互导入的最 Pythonic 的方法是什么? - What is the most pythonic way to import 'sibling' modules into one another? 将一个自定义类的序列映射到另一个自定义类的Python方法是什么? - What is the Pythonic way to map a sequence of one custom class to another? 在另一个 class 中引用 object 的 Pythonic 方式? - Pythonic way to reference an object in another class? 从对象获取属性的 Pythonic 方式是什么? - What is the Pythonic way of getting attributes from objects? 什么是pythonic方式有条件阴影? - What is the pythonic way to have conditional shadowing? 什么是在封闭范围内的赋值错误之前避免引用的Pythonic方法? - What is the Pythonic way to avoid reference before assignment errors in enclosing scopes? 在导入的代码库之间传递对象的Pythonic方法是什么? - What is the most Pythonic way to pass objects between imported libraries of code? 重新排序类对象属性的最pythonic方法是什么? - What is the most pythonic way to re-order a class objects' attributes? 从 **kwargs 实例化多个对象的 pythonic 方法是什么? - What's the pythonic way to instantiate multiple objects from **kwargs? 将行为添加到外部模块返回的对象的pythonic方法是什么? - What's the pythonic way to add behavior to objects returned by an external module?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM