synthetic properties

R

rowland

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
 
D

Diez B. Roggisch

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
 
B

Bruno Desthuilliers

(e-mail address removed) 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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,154
Members
46,702
Latest member
LukasConde

Latest Threads

Top