Python 中可相互引用的实例
Mutually Reference-able Instances in 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"
我不喜欢的是需要在两个地方指定关系。关于如何制作这款烘干机有什么想法吗?
我会把它分成三个 类:
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
就可以了。
同样,现在一只狗也可以属于多个主人
我会在 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'))
这种方法当然也可以只用于一只宠物,也可以将其扩展到允许许多人拥有宠物。
这里没有什么 Python-具体的;这只是基于构造函数的依赖注入的一个限制。很难注入对另一个尚未创建的对象的引用。相反,您可以创建一个引用某个对象的对象, 将 引用另一个对象。例如,您可以将一个函数传递给构造函数,该函数将能够 return 值:
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
当然,不难更新它以便 属性 函数缓存值。例如:
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_
假设我有一对相互引用的实例。是否有比以下更好的方式来构建这种关系。
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"
我不喜欢的是需要在两个地方指定关系。关于如何制作这款烘干机有什么想法吗?
我会把它分成三个 类:
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
就可以了。
同样,现在一只狗也可以属于多个主人
我会在 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'))
这种方法当然也可以只用于一只宠物,也可以将其扩展到允许许多人拥有宠物。
这里没有什么 Python-具体的;这只是基于构造函数的依赖注入的一个限制。很难注入对另一个尚未创建的对象的引用。相反,您可以创建一个引用某个对象的对象, 将 引用另一个对象。例如,您可以将一个函数传递给构造函数,该函数将能够 return 值:
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
当然,不难更新它以便 属性 函数缓存值。例如:
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_