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's __dict__,因为我还希望能够将字典作为参数传递,并可能在其他地方的 GameState 对象上使用 ** 。

4

3 回答 3

5

让 GameState 从 dict 继承:

class GameState(dict) 

并像这样重写 __setattr 函数:

def __setattr__(self,name,value) :
    self.__dict__[name] = value
    self[name] = value
于 2012-05-10T17:16:35.460 回答
2

为了**obj工作,你必须实现(或继承)__getitem__()andkeys()方法。

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
于 2012-05-10T17:20:01.937 回答
1

您可以通过在创建 b 时用a 的字典更新 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)

您可能想要创建 dict 的深层副本,因为您有一个列表对象作为属性的一部分。这更安全,因为没有对象共享。

于 2012-05-10T17:09:52.463 回答