Восстановление значений из именованных кортежей с использованием понимания списка внутри функции с декоратором свойств?

Я следую документации по Python и этот ответ SO также this, но я получаю указатель объекта свойства при использовании 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>

person Strapicarus    schedule 19.03.2017    source источник
comment
self.Keyboard по-прежнему является классом, а не экземпляром; когда вы создаете экземпляр, вы ничему его не назначаете. Почему бы не создать этот класс вне метода init и даже полностью вне DefaultSettings?   -  person jonrsharpe    schedule 19.03.2017
comment
Я только что сделал это, и результат тот же.   -  person Strapicarus    schedule 19.03.2017
comment
Почему бы тебе просто не return list(self.Keyboard)? Помимо имен, это все еще в основном кортеж значений.   -  person jonrsharpe    schedule 19.03.2017
comment
@jonrsharpe Я торопился и промахнулся. И я получаю тот же результат. Спасибо.   -  person Strapicarus    schedule 19.03.2017


Ответы (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')

Как сказано в документа namedtuple:

Возвращает новый кортеж subclass с именем typename

Таким образом, в первой строке метода __init__ вы создаете новый class и назначаете ему поле self.Keyboard, а в следующей строке вы создаете новый instance класса self.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')

Тогда вы получите нужные вам значения.

person shizhz    schedule 19.03.2017