On Aug 17, 5:09 pm, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > akonsu a écrit :> hello, > > > i need to add properties to instances dynamically during run time. > > this is because their names are determined by the database contents. > > so far i found a way to add methods on demand: > > > class A(object) : > > def __getattr__(self, name) : > > if name == 'test' : > > def f() : return 'test' > > setattr(self, name, f) > > return f > > else : > > raise AttributeError("'%s' object has no attribute '%s'" % > > (self.__class__.__name__, name)) > > > this seems to work and i can invoke method test() on an object. > > Nope. This adds per-instance *function* attributes - not *methods*. > > class A(object) : > def __getattr__(self, name) : > if name == 'test' : > def f(self) : > return "%s.test" % self > setattr(self, name, f) > return f > else : > raise AttributeError( > "'%s' object has no attribute '%s'" \ > % (self.__class__.__name__, name) > ) > > a = A() > a.test() > => Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: f() takes exactly 1 argument (0 given) > > To add methods on a per-instance basis, you have to manually invoke the > descriptor protocol's implementation of function objects: > > class A(object) : > def __getattr__(self, name) : > if name == 'test' : > def f(self) : > return "%s.test" % self > m = f.__get__(self, type(self)) > setattr(self, name, m) > return m > else : > raise AttributeError( > "'%s' object has no attribute '%s'" \ > % (self.__class__.__name__, name) > ) > > > it > > would be nice to have it as property though. so i tried: > > > class A(object) : > > def __getattr__(self, name) : > > if name == 'test' : > > def f() : return 'test' > > setattr(self, name, property(f)) > > return f > > else : > > raise AttributeError("'%s' object has no attribute '%s'" % > > (self.__class__.__name__, name)) > > > but this does not work, instance.test returns a callable but does not > > call it. > > Properties must be class attributes. The only way (the only way I know) > to get them to work as instance-attributes is to overload > __getattribute__, which is tricky and may have pretty bad impact on > lookup perfs - and ruins the whole point of using properties FWIW. > > > i am not an expert in python, would someone please tell me what i am > > doing wrong? > > 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 posted this to another thread, but... You can dynamically add properties (or anything else) 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 - Rafe -- http://mail.python.org/mailman/listinfo/python-list