Re: Externally-defined properties?

2005-08-25 Thread Michele Simionato
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?

2005-08-24 Thread Terry Hancock
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?

2005-08-24 Thread Bengt Richter
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?

2005-08-24 Thread Scott David Daniels
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