Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

adding properties dynamically (how to?)

204 views
Skip to first unread message

André

unread,
Aug 17, 2008, 8:51:59 AM8/17/08
to
I didn't want to hijack the original thread but I have basically the
same request...

On Aug 17, 7:09 am, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.fr> wrote:
> akonsu a écrit :> hello,
>
[SNIP]

>
> Wrong solution to your problem, I'd say. Let's start again:
>
> """
> > i need to add properties to instances dynamically during run time.
> > this is because their names are determined by the database contents.
> """
>
> Care to elaborate ? I may be wrong, but I suspect you're trying to roll
> your own python/database mapper. If so, there are quite a couple Python
> ORMs around. Else, please tell us more.

I'm not the original poster, but I'd like to do the same thing (for a
different reason).

I have a program (crunchy) that is extensible via plugins. New
options available via plugins can be turned on or off (or selected
among a list of options). I have a module for user preferences (let's
call it prefs.py) that allows the setting of these options (and do
error checking, automatic saving of the options selected for future
sessions, etc.). These options are implemented as properties.

Currently I have it simplified so that only two lines need to be added
to prefs.py to add new options; something like
options = { ...
'new_option': [value1, value2, ..., valueN],
...}

and
class Preferences(object):
...

new_option = make_property('new_option', 'some nicely worded help
string')

===
make_property is a custom define function that return fgets, fsets,
fdel and doc.

Ideally, I'd like to be able to define new would-be properties from
the plugin and add them to the class prior to creating instances. In
other words, have something like

===
for option in options_defined_in_plugins:
add_option_as_property_to_Preferences(Preferences, option, ...)

user_preferences = Preferences()

Performance in this case would not be an issue.

Cheers,

André

Bruno Desthuilliers

unread,
Aug 17, 2008, 7:09:20 AM8/17/08
to
André a écrit :

You may want to write your own descriptor object instead. The 'property'
class is just one possible way to use the descriptor protocol for
"smart" attributes.

> Ideally, I'd like to be able to define new would-be properties from
> the plugin and add them to the class prior to creating instances. In
> other words, have something like
>
> ===
> for option in options_defined_in_plugins:
> add_option_as_property_to_Preferences(Preferences, option, ...)
>
> user_preferences = Preferences()

Not the same problem as the OP here. Your properties are not
per-instance, so just adding them to the class is ok. Remember that in
Python, classes are objects too, and (a couple corner cases set aside)
nothing prevent you from dynamically adding attributes to an object. The
following snippets are equivalent:

class Foo1(object):
attrib = object()

class Foo2(object):
pass

Foo2.attrib = object()

class Foo3(object):
pass

setattr(Foo3, 'attrib', object())


Message has been deleted

Rafe

unread,
Aug 19, 2008, 1:59:59 PM8/19/08
to


Hi,

You can dynamically add properties to a class just before returning
the
instance using __new__():

class AClass(object):
def __new__(cls):

setattr(cls,"propName", property(fget = ...,
fset = ...,
fdel = ...,
doc = ...) )

obj = super(AClass, cls).__new__(cls)
return obj

You can put this in a for loop and add a property per option, etc. You
can also do this with your own descriptor if you make a custom one.

- Rafe

Bruno Desthuilliers

unread,
Aug 20, 2008, 5:11:29 AM8/20/08
to
Rafe a écrit :
(snip)

>
> You can dynamically add properties to a class

The OP was asking for *per instance* properties...

> just before returning
> the
> instance using __new__():
>
> class AClass(object):
> def __new__(cls):
>
> setattr(cls,"propName", property(fget = ...,
> fset = ...,
> fdel = ...,
> doc = ...) )
>
> obj = super(AClass, cls).__new__(cls)
> return obj


Very bad idea IMHO. __new__ is called on each instanciation, which means
the above code will uselessly modify the class each time you create an
instance of it, overwriting the same properties again and again and
again. If what you want is to automagically add properties (or whatever
type of attributes) to a class and/or it's subclass, you'd be better
using a custom metaclass.

0 new messages