I am coding for a Python plugin to some planetarium software. This plugin comes with functions for accessing objects within the planetarium software's namespace, but they are cumbersome and not OOP. I am therefore trying to create a class that would overload attribute access to streamline coding. I would like to be able to do things such as,
rocket = RemoteObject('rocket')
rocket.color = blue
to set the color of the rocket object in the planetarium software's namespace to blue.
How to define properties in __init__
comes quite close. One difficulty I'm having is that I need to determine the names of my properties when the instance is created. Another difficulty is due to my poor understanding of descriptors in general: attribute calls are returning or overwriting my property object itself instead of calling its getter and setter.
Here is what I have so far:
class RemoteObject(object):
def __init__(self,remote_object_name):
self.normalattr = 'foo'
self.normalmethod = lambda: 'spam'
for attrname in get_remote_object_attrnames(remote_object_name):
def _get(self):
return fetch_remote_attr_value(remote_object_name,attrname)
def _set(self,value):
set_remote_attr_value(remote_object_name,attrname,value)
setattr(self,attrname,property(_get,_set))
if __name__ == '__main__':
get_remote_object_attrnames = lambda name: {'apple','banana','cherry'}
fetch_remote_attr_value = lambda o,a: 'Reading %s.%s' % (o,a)
set_remote_attr_value = lambda o,a,v: 'Writing %s.%s = %s' % (o,a,v)
scene = RemoteObject('scene')
for x in scene.__dict__.items(): print x
print '-----'
print scene.normalattr
print scene.normalmethod()
print scene.apple
scene.banana = '42'
print '-----'
for x in scene.__dict__.items(): print x
When run, it returns this:
('cherry', <property object at 0x00CB65A0>)
('normalmethod', <function <lambda> at 0x00CB8FB0>)
('banana', <property object at 0x00CB65D0>)
('normalattr', 'foo')
('apple', <property object at 0x00CB6600>)
-----
foo
spam
<property object at 0x00CB6600>
-----
('cherry', <property object at 0x00CB65A0>)
('normalmethod', <function <lambda> at 0x00CB8FB0>)
('banana', '42')
('normalattr', 'foo')
('apple', <property object at 0x00CB6600>)
Is there a better way to handle the dynamic set of attrnames needing properties fro each instance? Why are the instance attibutes matching the property names returning the property object itself instead of executing its getter or setter?