In python getattr(obj, attr) == getattr(obj, attr) returns true. But in
each call. So the second call to getattr(obj, attr) returns a different
object than the first call, and thus are not equal.
d = dict()
x = [getattr(d, 'update')]
Original issue: http://code.google.com/p/pyjamas/issues/detail?id=394 (April 09, 2010 22:53:55)
From glenn.wa...@gmail.com on April 10, 2010 00:03:22:
Attaching a patch to libtest which adds tests for List.remove and getattr.
From luke.lei...@gmail.com on April 25, 2010 12:20:47:
thaank you glenn, this is an excellent find.
there is a way round this, which is to create a cache of getattr'd functions. this
would actually save a lot of time, apart from anything else.
From cornelis...@gmail.com on May 15, 2010 14:55:47:
Interesting idea. Caching might introduce memory leaks though (I think), or some
def foo(self): return 'foo'
c = C()
a = getattr(c, 'foo') # adds to getattr-cache for object c
del c # should delete from getattr-cache
or, more complicated:
c = C()
return getattr(c, 'foo')
a = bar() # object c should be deleted automatically from getattr-cache
We could give every object it's own private getattr_cache (some special attribute on
every object, e.g. getattr_cache).
Advantage: no housekeeping on delete, automatic removal of cache when object is deleted.
From cornelis...@gmail.com on May 15, 2010 14:59:12:
Hmm, on second thoughts:
a = getattr(c, 'foo')
b = getattr(c, 'foo')
a == b -> True
a is b -> False
The latter will result in True when the getattr for b comes from a cache.
From luke.lei...@gmail.com on June 08, 2010 14:20:05:
the generally accepted technique which i've seen is to add a local cached version of whatever attribute is being accessed.
ahh.... yes, of course: you'd need to delete that cached version if you changed the object.
From luke.lei...@gmail.com on June 16, 2010 20:05:52:
ok so wait... each object getattr'd has within it a cache of its own getattr-ness? :)
From cornelis...@gmail.com on June 17, 2010 07:43:41:
Yep. Every instance would get a getattr_cache dict / object
c.getattr_cache['foo'] = getattr(c, 'foo')
The getattr(c, 'foo') would probably need a cmp method
"del c" would keep "a" and delete the cache too, and an additional "del a" would release all references.
I'm still puzzled about the handling of "a is b", which will miserably fail in pyjs if we take the getattr from the cache.
The "a == b" can also be solved by just adding a cmp method to the object that's returned form getattr()
The performance gain of using a cache is not big (I think), since is only helps where the getattr function is called, while the major performance loss is in calling the object returned by getattr.
So, I'm hesitating to go in the direction of caching getattr objects.