2015-10-17 116 views
2

对于我正在做的游戏,我想创建一个对象,该对象的属性可以设置为另一个对象的属性(例如,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的吗?
我将如何实现它,以便它呢?

在你的代码
+1

它们是两个完全独立的对象,彼此之间没有引用。一个更新会如何影响另一个呢?在这两个字典中由'self.attributes'命名的字典是两个完全不同的字典。 – dursk

回答

0

,你真的不共享相同的字典,您可以创建在门的构造一个新的,尝试做:

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 

顺便说一句,在你提出我个人会作出锁门的成员的具体情况,并通过@property 共享属性,并取得了吸气,尽量从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) 

使用例子:这样做(至少是我喜欢)被定义Singleton

>>>l=Lock() 
>>>d=Door(l) 
>>>d.locked 
True 
>>>l.toggleLock() 
>>>d.locked 
False 
>>>d.attributes 
{'color': 'Blue', 'locked': False} 
+0

但是,如果我这样做,我会将整个'lock1.attributes'字典传递给'door1',无法分辨出我引用的是哪个键(大多数对象不仅仅是一个)。我应该只是传递一个元组与密钥和字典? ('door1 = door((lock1.attributes,'locked'))'),然后在'door1'内拉出给定键的值? – Caketray

+0

如果你只想在你的两个类中共享词典中的特定项目,你需要他们指向一个对象的同一个实例,我会简单地将这个值包装在一个类中,我将用一个例子编辑答案 – DorElias

+0

你能举一个例子说明你如何用@property来做到这一点吗? – Caketray

0

的一种可能方式。注意,这是有效的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类创建的所有的锁将共享相同的对象,因此相同的状态。

相关问题