properties and get/set methods

Greg Chapman glc at well.com
Sun Apr 6 18:31:33 CEST 2003


On Sat, 05 Apr 2003 23:48:41 -0500, "Mike C. Fletcher" <mcfletch at rogers.com>
wrote:

>As for how the problem ((a deficiency in the property API IMO) of not 
>knowing the name being set/get within the get/set methods) gets worked 
>around.  I (as seen above) do some comparatively minor (but still 
>annoying) duplication of code by passing an explicit string version of 
>the name to the property sub-class's constructor and then use that name 
>when the property instances are called.  Technically, the string value 
>can be anything, and certain sub-classes of property just ignore it, 
>while in any case, it can be something different than the "public" name 
>through which the property API calls were made :( .
>
>i.e. this works, storing the value as instance.__dict__['_myProperty']:
>
>    myProperty = StringProperty(
>       "_myProperty", """Some documentation""",
>       defaultValue = "this value",
>    )
>
>but the property doesn't know what name it's _really_ being accessed as 
>in this case :( .

You could always use somthing like this:

import sys
import re
import inspect
from compiler.misc import mangle

# seems like this ought to be built in someplace, but I couldn't find it
def isident(name):
    return bool(re.match('[A-Za-z_][A-Za-z_0-9]*$', name))

def DeclareProperty(name, doc, defvalue):
    frame = sys._getframe(1)
    framecode = frame.f_code
    codename = framecode.co_name
    inclassdef = (                 #not a perfect test by any means
        not (framecode.co_flags & inspect.CO_OPTIMIZED) and
        isident(codename)
    )
    if inclassdef and name.startswith('__'):
        name = mangle(name, codename)
    def getter(obj):
        return obj.__dict__.get(name, defvalue)
    def setter(obj, value):
        obj.__dict__[name] = value
    prop = property(getter, setter, doc=doc)
    if inclassdef:    
        frame.f_locals[name] = prop
    return prop                  #in case you want to use this outside
                                 #a class def

class Test(object):
    DeclareProperty('myProperty', 'Some documentation', 'default value')


---
Greg Chapman





More information about the Python-list mailing list