对于我正在制作的游戏,我想创建一个具有可以设置为另一个对象的属性的属性的对象(例如,door.locked = lock.locked)。当我更新第二个对象的属性(在本例中为lock
)时,第一个对象(door
)的相应属性也应该更新。这样解锁锁也将解锁门。
我目前用字典实现了这个,如下所示:
class Lock():
def __init___(self, locked = True):
self.attributes = {'locked': locked}
def toggleLock():
self.attributes.update({'locked': not self.attributes['locked']})
class Door():
def __init__(self, locked = False):
self.attributes = {'locked': locked}
然后我应该能够做到这一点:
>>>lock1 = Lock(locked = True)
>>>door1 = Door(locked = lock1.attributes['locked'])
>>>
>>>lock1.attributes['locked']
True
>>>door1.attributes['locked']
True
>>>
>>>lock1.toggleLock()
>>>lock1.attributes['locked']
False
>>>door1.attributes['locked']
False
然而,当我调用toggleLock()
方法时,锁的状态会发生变化但门却没有。字典是可变的,所以当door1
的时候不应该lock1
字典更新吗?
我将如何实现它呢?
答案 0 :(得分:0)
在你的代码中,你真的没有共享同一个字典,你在Door的构造函数中创建了一个新字典,试着这样做:
class Door():
def __init__(self, attributes):
self.attributes = attributes
然后按照这样的方式调用它:
>>>lock1 = Lock(locked = True)
>>>door1 = Door(lock1.attributes)
编辑:
如果你想拥有不同的词典并且只共享值,那么你可能想要将值包装在一个类中,然后共享它的一个实例:
class SharedValue(object):
def __init__(self, val):
self.value = val
class Lock():
def __init___(self, locked = True):
self.attributes = {'locked': SharedValue(locked)}
def toggleLock():
self.attributes['locked'].value = not self.attributes['locked'].value
class Door():
def __init__(self, locked = False):
if not isinstance(locked, SharedValue):
locked = SharedValue(locked)
self.attributes = {'locked': locked}
然后您可以按照自己的意愿创建它,但使用该值的代码必须更改
>>>lock1 = Lock(locked = True)
>>>door1 = Door(locked = lock1.attributes['locked'])
>>>
>>>lock1.attributes['locked'].value
True
>>>door1.attributes['locked'].value
True
顺便说一句,在您提交的具体案例中,我个人会将Lock锁定为Door的成员,并通过@property分享属性
并制作了getter,尝试从self.attributes
获取它并且如果它不包含密钥,则从self.lock.attribute
获取它
EDIT2:
为不同的解决方案添加示例:
class Lock():
def __init__(self, locked = True):
self.attributes = {'locked': locked}
def toggleLock(self):
self.attributes.update({'locked': not self.attributes['locked']})
class Door():
def __init__(self, lock_object):
self._attributes = {'color':'Blue'}
self.lock = lock_object
def get_attribute(self,key):
if key in self._attributes:
return self._attributes[key]
elif key in self.lock.attributes:
return self.lock.attributes[key]
raise KeyError(key)
@property
def attributes(self):
"""
Door's attributes
"""
# return a new dict that contains the keys of itself, and lock (and possibly more objects)
a = {}
a.update(self.lock.attributes)
a.update(self._attributes)
return a
def __getattr__(self, key):
#nice addition, makes you able to do things like `if Door.locked:`
return self.get_attribute(key)
用法示例:
>>>l=Lock()
>>>d=Door(l)
>>>d.locked
True
>>>l.toggleLock()
>>>d.locked
False
>>>d.attributes
{'color': 'Blue', 'locked': False}
答案 1 :(得分:0)
这样做的一种可能方式(至少我更喜欢)是定义Singleton
。请注意,这对python 2.x有效,我不知道它是否适用于Python 3.x
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args) # , **kwargs
return cls._instances[cls]
然后将此类别转移到您的锁类
class Lock():
__metaclass__ = Singleton
def __init___(self, locked = True):
self.attributes = {'locked': locked}
def toggleLock():
self.attributes.update({'locked': not self.attributes['locked']})
简单地说,Singleton
只允许您创建该对象的一个实例。第一次调用将创建一个新对象,之后调用将不会创建一个新对象,但会返回第一次调用创建的旧对象。
door_1_status = Lock() # will create a Lock object
door_2_status = Lock() # will not crate a new Lock, but return the already created Lock object.
因此,从Lock
类创建的所有锁将共享相同的对象,因此状态相同。