2015-10-17 114 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類創建的所有的鎖將共享相同的對象,因此相同的狀態。

相關問題