Python中可相互引用的实例

2024-05-16 03:01:47 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一对相互引用的实例。有没有比下面更好的方式来构建这种关系。你知道吗

class Human():
    def __init__(self, name):
        self.name = name
        self.pet = Dog('Sparky', self)

    def pet(self, animal):
        self.pet.receive_petting()


class Dog(Pet):
    def __init__(self, name, owner):
        self.name = name
        self.owner = owner

    def receive_petting(self):
        pass

    def bark_at(self, person):
        "do something"

我不喜欢的是,这种关系需要在两个地方具体说明。你知道怎么做这个烘干机吗?你知道吗


Tags: 实例nameself关系initdef方式class
3条回答

这里没有真正特定于Python的东西;这只是基于构造函数的依赖注入的一个限制。很难将引用注入到另一个尚未创建的对象。相反,您可以创建一个对象,该对象包含对某个对象的引用,而包含对另一个对象的引用。例如,您可以将一个函数传递给能够返回值的构造函数:

class Human():
    def __init__(self,name,dog):
        self.name = name
        self._dog = dog

    @property
    def dog(self):
        return self._dog()


class Dog():
    def __init__(self,name,human):
        self.name = name
        self._human = human

    @property
    def human(self):
        return self._human()

然后你可以这样使用它:

human = None
dog = Dog('fido',lambda: human)
human = Human('john',lambda: dog)

print(dog.human.name)
print(human.dog.name)
john
fido

当然,要更新它以便property函数缓存值并不难。例如:

class Dog():
    def __init__(self,name,human):
        self.name = name
        self._human = human

    @property
    def human(self):
        try:
            return self._human_
        except AttributeError:
            self._human_ = self._human()
            return self._human_

我将在Human上创建一个方法,允许您添加宠物(因为人类可能有许多宠物):

class Human():
    def __init__(self, name):
        self.name = name
        self.pets = []

    def add_pet(self, pet):
        pet.owner = self
        self.pets.append(pet)

    def pet(self, animal):
        for pet in self.pets:
            pet.receive_petting()


class Dog(Pet):
    def __init__(self, name):
        self.name = name
        self.owner = None

    def receive_petting(self):
        pass

    def bark_at(self, person):
        "do something"

可按如下方式使用

human = Human('Jim')
human.add_pet(Dog('Woof'))

当然,这种方法也可以只用于一只宠物,也可以扩展到允许宠物归许多人所有。你知道吗

我会把它分成三类:

class Human():
    def __init__(self, name):
        self.name = name

class Dog(Pet):
    def __init__(self, name):
        self.name = name

    def bark_at(self, person):
        "do something"

class OwnerPetRelation():
    def __init__(self, dog, human):
        self.owner=human
        self.pet=dog

现在,一个主人也可以养很多狗,我们只需要定义尽可能多的OwnerPetRelation

同样,一条狗现在也可以属于多个主人。你知道吗

相关问题 更多 >