如何创建在 Python 中动态更新的列表属性?
How can I create a list attribute that updates dynamically in Python?
我有两个 class 以一对多的关系相互引用(下例中的 Kid
和 Toy
)。当我将新的 Toy
分配给 Kid
时,我希望 Kid
也分配给 Toy
。
基于列表为 toys
属性创建自定义 class 并重新定义方法(例如 append
、extend
、delete
)会起作用,但是我想知道有没有更好的方法。
class Toy:
def __init__(self, name, kid=None):
self.name = name
self.kid = kid
class Kid:
def __init__(self, name, toys):
self.name = name
self.toys = toys
@property
def toys(self):
return self._toys
@toys.setter
def toys(self, val):
self._toys = val
# Assign the kid to the toys
for toy in self._toys:
toy.kid = self
if __name__ == "__main__":
toys = [Toy('Woodie'), Toy('Slinky'), Toy('Rex')]
andy = Kid('Andy', toys)
# Andy corrected assigned to toys
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
print('-')
# Add new toy
andy.toys.append(Toy('Buzz'))
# Throws error because Buzz is not assigned Andy
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
输出:
Woodie Andy
Slinky Andy
Rex Andy
-
Woodie Andy
Slinky Andy
Rex Andy
Traceback (most recent call last):
File "c:/Users/jonat/Desktop/tests/inheritance_q.py", line 34, in <module>
print('{}\t{}'.format(toy.name, toy.kid.name))
AttributeError: 'NoneType' object has no attribute 'name'
我希望 Buzz
被分配 Andy
。
您可以在您的 Kid 中添加一个方法 class:
class Toy:
def __init__(self, name, kid=None):
self.name = name
self.kid = kid
class Kid:
def __init__(self, name, toys):
self.name = name
self.toys = toys
@property
def toys(self):
return self._toys
@toys.setter
def toys(self, val):
self._toys = val
# Assign the kid to the toys
for toy in self._toys:
toy.kid = self
def give_toy(self, toy):
toy.kid = self
self.toys.append(toy)
if __name__ == "__main__":
toys = [Toy('Woodie'), Toy('Slinky'), Toy('Rex')]
andy = Kid('Andy', toys)
# Andy corrected assigned to toys
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
print('-')
# Add new toy
andy.give_toy(Toy('Buzz'))
# Throws error because Slinky is not assigned Andy
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
输出:
Woodie Andy
Slinky Andy
Rex Andy
-
Woodie Andy
Slinky Andy
Rex Andy
Buzz Andy
我有两个 class 以一对多的关系相互引用(下例中的 Kid
和 Toy
)。当我将新的 Toy
分配给 Kid
时,我希望 Kid
也分配给 Toy
。
基于列表为 toys
属性创建自定义 class 并重新定义方法(例如 append
、extend
、delete
)会起作用,但是我想知道有没有更好的方法。
class Toy:
def __init__(self, name, kid=None):
self.name = name
self.kid = kid
class Kid:
def __init__(self, name, toys):
self.name = name
self.toys = toys
@property
def toys(self):
return self._toys
@toys.setter
def toys(self, val):
self._toys = val
# Assign the kid to the toys
for toy in self._toys:
toy.kid = self
if __name__ == "__main__":
toys = [Toy('Woodie'), Toy('Slinky'), Toy('Rex')]
andy = Kid('Andy', toys)
# Andy corrected assigned to toys
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
print('-')
# Add new toy
andy.toys.append(Toy('Buzz'))
# Throws error because Buzz is not assigned Andy
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
输出:
Woodie Andy
Slinky Andy
Rex Andy
-
Woodie Andy
Slinky Andy
Rex Andy
Traceback (most recent call last):
File "c:/Users/jonat/Desktop/tests/inheritance_q.py", line 34, in <module>
print('{}\t{}'.format(toy.name, toy.kid.name))
AttributeError: 'NoneType' object has no attribute 'name'
我希望 Buzz
被分配 Andy
。
您可以在您的 Kid 中添加一个方法 class:
class Toy:
def __init__(self, name, kid=None):
self.name = name
self.kid = kid
class Kid:
def __init__(self, name, toys):
self.name = name
self.toys = toys
@property
def toys(self):
return self._toys
@toys.setter
def toys(self, val):
self._toys = val
# Assign the kid to the toys
for toy in self._toys:
toy.kid = self
def give_toy(self, toy):
toy.kid = self
self.toys.append(toy)
if __name__ == "__main__":
toys = [Toy('Woodie'), Toy('Slinky'), Toy('Rex')]
andy = Kid('Andy', toys)
# Andy corrected assigned to toys
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
print('-')
# Add new toy
andy.give_toy(Toy('Buzz'))
# Throws error because Slinky is not assigned Andy
for toy in andy.toys:
print('{}\t{}'.format(toy.name, toy.kid.name))
输出:
Woodie Andy
Slinky Andy
Rex Andy
-
Woodie Andy
Slinky Andy
Rex Andy
Buzz Andy