2012-05-10 38 views
0

我有一個類定義,像這樣:讓班級充當字典嗎?

class GameState: 

    def __init__(self, state=None): 
     if state is None: 
      self.fps = 60 
      self.speed = 1 
      self.bounciness = 0.9 
      self.current_level = None 

      self.next_frame_time = 0 
      self.init_time = 0 
      self.real_time = 0 
      self.game_time = 0 

      self.game_events = [] 
      self.real_events = [] 
     else: 
      # THIS being the key line: 
      self.__dict__.update(**state) 

有一個接口,我可以定義,使得該作品(即**操作符對我的課):

>>> a = GameState() 
>>> b = GameState(a) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: update() argument after ** must be a mapping, not GameState 

從本質上講,我想b承擔所有的a屬性。

我不認爲這是可行的,但我想定義__getitem__沒有任何的運氣。

編輯:我想避免使用B的__dict__,因爲我想也能夠通過一本字典作爲參數,並有可能使用**在遊戲狀態對象的其他地方。

回答

2

爲了**obj工作,你必須實現(或繼承)的__getitem__()keys()方法。

def __getitem__(self, item): 
    return self.__dict__[item] # you maybe should return a copy 
def keys(self): 
    return self.__dict__.keys() # you could filter those 
+0

完美,這就是我一直在尋找! :) – Darthfett

1

你可以通過更新b的字典與創建b時的那個來做到這一點。嘗試了這一點:

class GameState: 

    def __init__(self, state=None): 
     if state is None: 
      self.fps = 60 
      self.speed = 1 
      self.bounciness = 0.9 
      self.current_level = None 

      self.next_frame_time = 0 
      self.init_time = 0 
      self.real_time = 0 
      self.game_time = 0 

      self.game_events = [] 
      self.real_events = [] 
     else: 
      if type(state) is dict: 
       self.__dict__.update(**state) 
      else: 
       self.__dict__.update(**state.__dict__) 

a = GameState() 
b = GameState(a) 

您可能希望創建字典的deepcopy的,因爲你有一個清單對象的屬性的一部分。由於沒有共享對象,因此更安全。

+0

我應該把這個問題中(見我的編輯),但我希望避免使用的'__dict__',因爲我想**操作對象上工作。 – Darthfett

+0

你可以測試的狀態類型。如果它是Gamestate類型的對象,那麼你使用'__dict__',否則你只是作爲一個正常的字典使用。 – cobie

+0

我不希望有這樣做的任何地方可以使用遊戲狀態。我也想'try:self .__ dict __。update(** state);除了TypeError:self .__ dict __。update(** state .__ dict __)''可能更加pythonic。使用'type'是檢查對象類型的錯誤方法。 – Darthfett

5

讓遊戲狀態從字典繼承:

class GameState(dict) 

並重寫__setattr功能是這樣的:

def __setattr__(self,name,value) : 
    self.__dict__[name] = value 
    self[name] = value 
+0

這是否對所有內容使用'__dict__',或者我需要使用'self [name]'來定義一個自定義'__getattr__'來查找名稱,以便讓我現有的'__init__'工作? – Darthfett

+1

與__setattr__此外,這將是一個既字典和一個普通對象 –

+0

啊,謝謝!我不確定'dict'會提供什麼其他功能,所以我試圖儘可能輕量化,所以我將使用ch3ka的解決方案,它提供了最小的界面。 upvote爲有用的答案,但。 :) – Darthfett