-1

I'm following the python documentation and this SO answer also this but i'm getting a property object pointer when using getattr and im unable to get or print the value i'm looking for.

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))

and the outputs:

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>
Community
  • 1
  • 1
Strapicarus
  • 131
  • 1
  • 5
  • 1
    `self.Keyboard` is still the class, not the instance; when you create the instance you don't assign it to anything. Why not create that class *outside* the init method, and even outside `DefaultSettings` entirely? – jonrsharpe Mar 19 '17 at 00:58
  • I just did that and the output is the same. – Strapicarus Mar 19 '17 at 01:06
  • 1
    Why don't you just `return list(self.Keyboard)`? Names aside, it's still basically a tuple of values. – jonrsharpe Mar 19 '17 at 01:07
  • @jonrsharpe I was in a hurry and miss typed it. And i get same output. Thanks. – Strapicarus Mar 19 '17 at 02:03

1 Answers1

1

The problem is in your __init__ method:

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')

As the doc of namedtuple says:

Returns a new tuple subclass named typename

So in your first line of __init__ method, you init a new class and assgin it it field self.Keyboard, and in the following line you create a new instance of class self.Keyboard but assign it to nowhere, the self.Keyboard is still a class object. So what the following codes doing is iterating/printing properties and methods of a class, not an instance. I guess what you want might be:

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')

Then you'll get the values you want.

shizhz
  • 11,715
  • 3
  • 39
  • 49