Re: Externally-defined properties?
Well, I have used factories of properties external to the class many times, and they work pretty well. Michele Simionato -- http://mail.python.org/mailman/listinfo/python-list
Externally-defined properties?
Frankly, I was surprised this worked at all, but I tried creating a property outside of a class (i.e. at the module level), and it seems to behave as a property: def get_x(ob): ... global x ... return str(x) ... def set_x(ob, value): ... global x ... x = int(value) ... def del_x(ob): ... global x ... del x ... def x_access(): ... return property(get_x, set_x, del_x, X defined externally?) ... class Accessor(object): ... s_x = x_access() ... def __str__(self): ... print Accessor has x = %s % self.s_X ... a = Accessor() a.s_x = 3 a.s_x '3' dir() ['Accessor', '__builtins__', '__doc__', '__name__', 'a', 'del_x', 'get_x', 'p', 'set_x', 'x', 'x_access'] x 3 (of course in the real example, x will probably be in an entirely different module, used as a library -- the client code just calls a function to get a property that is automatically managed for it). So far, the only problem I see is that it only works if the property is assigned to a new-type class attribute (otherwise, the first assignment simply replaces the property). I'm thinking of using this to tie a property of a class to an external data source (a joystick axis, in fact -- or at least its last-polled value). There is a more convential way to do this, of course -- I could just use a get_value function, but there is something attractive about have a variable that is simply bound to the external data source like this. It seems like a good way to encapsulate functionality that I don't really want the high level class to have to think about. I mention it here, because I've never seen a property used this way. So I'm either being very clever, or very dumb, and I would be interested in opinions on which applies. ;-) Am I about to shoot myself in the foot? Cheers, Terry -- Terry Hancock ( hancock at anansispaceworks.com ) Anansi Spaceworks http://www.anansispaceworks.com -- http://mail.python.org/mailman/listinfo/python-list
Re: Externally-defined properties?
On Wed, 24 Aug 2005 01:15:03 -0500, Terry Hancock [EMAIL PROTECTED] wrote: Frankly, I was surprised this worked at all, but I tried creating a property outside of a class (i.e. at the module level), and it seems to behave as a property: def get_x(ob): ... global x ... return str(x) ... def set_x(ob, value): ... global x ... x = int(value) ... def del_x(ob): ... global x ... del x ... def x_access(): ... return property(get_x, set_x, del_x, X defined externally?) ... class Accessor(object): ... s_x = x_access() ... def __str__(self): ... print Accessor has x = %s % self.s_X ... a = Accessor() a.s_x = 3 a.s_x '3' dir() ['Accessor', '__builtins__', '__doc__', '__name__', 'a', 'del_x', 'get_x', 'p', 'set_x', 'x', 'x_access'] x 3 (of course in the real example, x will probably be in an entirely different module, used as a library -- the client code just calls a function to get a property that is automatically managed for it). So far, the only problem I see is that it only works if the property is assigned to a new-type class attribute (otherwise, the first assignment simply replaces the property). I'm thinking of using this to tie a property of a class to an external data source (a joystick axis, in fact -- or at least its last-polled value). There is a more convential way to do this, of course -- I could just use a get_value function, but there is something attractive about have a variable that is simply bound to the external data source like this. It seems like a good way to encapsulate functionality that I don't really want the high level class to have to think about. I mention it here, because I've never seen a property used this way. So I'm either being very clever, or very dumb, and I would be interested in opinions on which applies. ;-) Am I about to shoot myself in the foot? ISTM you are basically exploiting your freedom to define the getter/setter/deleter functions of a property any way you please. Another way, if you just want a proxy object whose property attributes access designated other objects' attributes, you could use a custom descriptor class, e.g., class Indirect(object): ... def __init__(self, tgtattr, tgtobj): ... self.tgtattr = tgtattr ... self.tgtobj = tgtobj ... def __get__(self, inst, cls=None): ... if inst is None: return self ... return getattr(self.tgtobj, self.tgtattr) ... def __set__(self, inst, value): ... setattr(self.tgtobj, self.tgtattr, value) ... def __delete__(self, inst): ... delattr(self.tgtobj, self.tgtattr) ... A place to put properties: class Accessor(object): pass ... An example object to access indirectly class Obj(object): pass ... obj = Obj() Making Accessor instance attribute 'xobj' access 'obj' attribute of Obj instance obj Accessor.xobj = Indirect('obj', obj) An Accessor instance to use for the property attribute magic a = Accessor() Set obj.obj = 123 indirectly a.xobj = 123 Check vars(obj) {'obj': 123} Set up access to an object attribute in a different module import sys Accessor.sin = Indirect('stdin', sys) a.sin open file 'stdin', mode 'r' at 0x02E8E020 Accessor.pi = Indirect('pi', __import__('math')) a.pi 3.1415926535897931 a.pi = 3 a.pi 3 import math math.pi 3 I'd say there's possibilities for shooting yourself in the foot. Maybe passing a code to Indirect to enable get/set/del selectively would help. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list
Re: Externally-defined properties?
Terry Hancock wrote: Frankly, I was surprised this worked at all, but I tried creating a property outside of a class (i.e. at the module level), and it seems to behave as a property: Not so surprising. Making a class begins by making a little namespace, then using it to build the class. If you look at how class construction works, it gets handed the namespace to wrap parts (the originals are left alone). After playing with your example for a little, perhaps the following will illustrate things: def get_x(obj): return thevar def set_x(obj, val): global thevar thevar = val def del_x(obj): global thevar del thevar def textify(obj): objid = '%s_%s' % (obj.__class__.__name__, id(obj)) try: return '%s:%r' % (objid, thevar) except (NameError, AttributeError): return '%s:---' % objid prop = property(get_x, set_x, del_x) class One(object): x = prop __repr__ = textify class Two(object): y = prop __str__ = textify Class Three(object): __repr__ = textify a = One() b = Two() c = Three() print a, b, c a.x = 5 print a.x, b.y, a, b, c Three.z = One.x print c, c.z del b.y print a, b, c print a.x You may want to raise AttributeError on get_x (you have no name to use): def get_x(obj): try: return thevar except NameError: raise AttributeError Am I about to shoot myself in the foot? Well, usually all this playing is good for understanding how Python works, but makes your connections less than explicit, and we know that explicit is better than implicit. --Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list