It is good to adopt that skeptical approach, rather than just accept that it works, because otherwise you might get tripped up by unexpected behaviours.
The answer is that when you create a Keyboard
object, it comes with a batch of properties and methods defined for it:
>>> from psychopy.hardware import keyboard
>>> k = keyboard.Keyboard()
>>> k.keys
[]
i.e. .keys
is initialised as an empty list. If a Keyboard
object didn’t already have a .keys
attribute defined, then we would get an error when trying to assign to it.
When in doubt, if you want to know what attributes an object has, use the dir()
function:
>>> dir(k)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_buffers', '_devs', '_ids', 'clearEvents', 'clock',
'corr', 'getKeys', 'keys', 'rt', 'start', 'status', 'stop', 'time',
'waitKeys']
many of the “dunder” ones (ones with double underscores) can be ignored as they are generally generic things Python needs. The ones that are likely of most interest to you are at the end of the list.
Lastly, for clarity, please do this for posting code (have edited the posts above):