|  | synthetic properties |  | |
| | | Guest |  |
| Posted: Tue Sep 02, 2008 7:48 pm Post subject: synthetic properties |  |
| |  | |
I'm trying to come up with solution for adding synthetic properties to python, similar to synthetic properties in Objective-C.
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.
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__? The hard part I'm guessing is getting the current instance passed into the getter. 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 )
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
Thanks, Rowland |
| |
| | | Diez B. Roggisch |  |
| Posted: Tue Sep 02, 2008 7:48 pm Post subject: Re: synthetic properties |  |
rowland@river2sea.org schrieb:
| Quote: | I'm trying to come up with solution for adding synthetic properties to python, similar to synthetic properties in Objective-C.
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.
|
Why on earth do you want to do that? The reason synthesized properties exist in ObjC is simply that to expose properties for key-value-coding, one needs the getter/setters. But mostly these are boilerplate, so apple introduced the @synthesized-annotation.
But in python, you don't need that. You use simple attributes. In the very moment you need logic attached, use the builtin property to do so.
Diez |
| |
| | | Bruno Desthuilliers |  |
| Posted: Tue Sep 02, 2008 7:48 pm Post subject: Re: synthetic properties |  |
| |  | |
rowland@river2sea.org a écrit :
| Quote: | 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...
| Quote: | 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.
| Quote: | 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.
| Quote: | The hard part I'm guessing is getting the current instance passed into the getter.
|
Not really.
| Quote: | 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.
| Quote: | 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 |
| |
|
|