synthetic properties
Bruno Desthuilliers
bdesth.quelquechose at free.quelquepart.fr
Tue Sep 2 16:45:25 EDT 2008
rowland at river2sea.org a écrit :
> I'm trying to come up with solution for adding synthetic properties to
> python, similar to synthetic properties in Objective-C.
Please explain what Objective-C "synthetic properties" are - not
everyone here has a strong Objective-C background...
> I'm playing around with doing this in a MetaClass. I can dynamically
> create the attributes that will back the property, but I'm having
> trouble figuring out how to dynamically generate get/set methods to
> pass to the built-in property() function.
FWIW, the property type is just one possible application of the
descriptor protocol. You can easily define your own custom descriptor
classes - and you can even do this dynamically.
> Is it possible to define a lambda or a callable object that will act
> as a getter method (or setter, that takes a value argument) during
> MetaClass.__init__?
Yes.
> The hard part I'm guessing is getting the current
> instance passed into the getter.
Not really.
> This is my first foray into
> MetaClasses and dynamic functions/methods so any pointers are greatly
> appreciated.
>
>
> class ObjectivePythonObject( type ) :
>
> def __new__( cls, name, bases, dct ) :
> #print "Allocating memory for class", name
> return type.__new__(cls, name, bases, dct )
This is what type.__new__ do, so you just don't need it.
> def __init__( cls, name, bases, dct ) :
> #print "Initializing class", name
> for propertyInfo in cls.synthesized :
> property = propertyInfo[ 0 ]
> defaultValue = propertyInfo[ 1 ]
> print property
> setattr( cls, '_' + property, defaultValue )
> # Create property with get/set methods...
>
> class Person( object ) :
>
> __metaclass__ = ObjectivePythonObject
>
>
> synthesized = [ ( 'name', 'BobC' ),
> ( 'age', '48' ) ]
>
> def __init__( self ) :
> print self._name
> print self._age
>
<side-note>
May I suggest you read about Python's coding conventions ? Your code
formatting is utterly unpythonic...
</side-note>
Ok, here's a working (and slightly more pythonic - at least wrt/ coding
style) version of your code:
def _make_prop(attrname, default):
def fget(self):
return getattr(self, attrname, default)
def fset(self, value):
setattr(self, attrname, value)
return property(fget=fget, fset=fset)
class ObjectivePythonType(type) :
def __init__(cls, name, bases, dct):
# we don't want to redefine properties already
# defined in a base class
synthesized = dct.get('synthesized', ())
for propname, default in synthesized:
attrname = "_%s" % propname
setattr(cls, propname, _make_prop(attrname, default))
class ObjectivePythonObject(object):
__metaclass__ = ObjectivePythonType
class Person(ObjectivePythonObject):
synthesized = [
('name', 'BobC'),
('age', '48'),
]
def __init__(self) :
print self.name
print self.age
Now... While all this is certainly usefull as a learning exercice on
metaclasses etc, it's also an awfully overcomplexificated way to do
something quite simple. Here's some code that do exactly the same thing:
class PythonPerson(object):
name = "BobC"
age = "48"
def __init__(self):
print self.name
print self.age
HTH
More information about the Python-list
mailing list