使用属性装饰器在函数内使用列表解析从命名元组中恢复值?

时间:2017-03-19 00:52:51

标签: python python-2.7 namedtuple getattr

我跟随python documentationthis SO answerthis,但我在使用getattr并且无法获取或打印值时获取属性对象指针我正在寻找。

class DefaultSettings():
    """This contains default game settings."""
    def __init__(self):
        """Default settings"""
        self.Keyboard = namedtuple('Keyboard', ['gas', 'reverse', 'sbreak', 'ebreak', 'left', 'right'])
        self.Keyboard(gas = 'WKEY', reverse = 'SKEY', sbreak = 'SKEY', ebreak = 'SPACEKEY', left = 'AKEY', right = 'DKEY')
    @property
    def keyboard(self):
        return [getattr(self.Keyboard, key) for key in self.Keyboard._fields]

settings = DefaultSettings()
print("keyboard 1: ",settings.keyboard)
print("Keyboard 2: ",settings.Keyboard)
print("keyboard 3: ",settings.Keyboard._fields)
print("Keyboard 4: ", DefaultSettings.keyboard.__get__)
print("Keyboard 5: ", DefaultSettings.keyboard.__get__(settings, DefaultSettings))
for key in settings.Keyboard._fields:
    print(getattr(settings.Keyboard, key))

和输出:

D:\Games\BSR\scripts>python config.py
keyboard 1:  [<property object at 0x000001C18DDC4778>, <property object at 0x000001C18DDC4AE8>, <property object at 0x000001C18DDC4B38>, <property object at 0x000001C18DDC4B88>, <property object at 0x000001C18DDC4BD8>, <property object at 0x000001C18DDC4C28>]
Keyboard 2:  <class '__main__.Keyboard'>
keyboard 3:  ('gas', 'reverse', 'sbreak', 'ebreak', 'left', 'right')
Keyboard 4:  <method-wrapper '__get__' of property object at 0x000001C18DDC4598>
Keyboard 5:  [<property object at 0x000001C18DDC4778>, <property object at 0x000001C18DDC4AE8>, <property object at 0x000001C18DDC4B38>, <property object at 0x000001C18DDC4B88>, <property object at 0x000001C18DDC4BD8>, <property object at 0x000001C18DDC4C28>]
<property object at 0x000001C18DDC4778>
<property object at 0x000001C18DDC4AE8>
<property object at 0x000001C18DDC4B38>
<property object at 0x000001C18DDC4B88>
<property object at 0x000001C18DDC4BD8>
<property object at 0x000001C18DDC4C28>
D:\Games\BSR\scripts>

1 个答案:

答案 0 :(得分:1)

问题在于您的__init__方法:

def __init__(self):
    """Default settings"""
    self.Keyboard = namedtuple('Keyboard', ['gas', 'reverse', 'sbreak', 'ebreak', 'left', 'right'])
    self.Keyboard(gas = 'WKEY', reverse = 'SKEY', sbreak = 'SKEY', ebreak = 'SPACEKEY', left = 'AKEY', right = 'DKEY')

正如the doc of namedtuple所说:

  

返回名为typename

的新元组subclass

因此,在__init__方法的第一行中,您初始化一个新的class并将其分配到self.Keyboard字段,然后在以下行中创建一个新的instanceself.Keyboard但是将它分配给无处,self.Keyboard仍然是一个类对象。那么以下代码所做的是迭代/打印class的属性和方法,而不是实例。我想你想要的可能是:

def __init__(self):
    Keyboard = namedtuple('Keyboard', ['gas', 'reverse', 'sbreak', 'ebreak', 'left', 'right'])
    self.Keyboard = Keyboard(gas = 'WKEY', reverse = 'SKEY', sbreak = 'SKEY', ebreak = 'SPACEKEY', left = 'AKEY', right = 'DKEY')

然后您将获得所需的值。