adding methods at runtime and lambda

Peter Otten __peter__ at web.de
Fri May 4 17:46:21 EDT 2007


Mike wrote:

> I just realized in working with this more that the issues I was having
> with instancemethod and other things seems to be tied solely to

What you describe below is a function that happens to be an attribute of an
instance. There are also "real" instance methods that know about "their"
instance:

>>> import new
>>> class A(object):
...     def __init__(self, name):
...             self.name = name
...
>>> def method(self): # a function...
...     print self.name
...
>>> a = A("alpha")
>>> b = A("beta")
>>> a.method = new.instancemethod(method, a) # ...turned into a method...
>>> a.method()
alpha
>>> b.method() # ... but only known to a specific instance of A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'method'

> builtins like dict or object. I remember at some point just doing
> something like:
> 
> x.fn = myfnFunction
> 
> and having it just work. 

With the caveat that x.fn is now an alias for myfnFunction, but doesn't get
x passed as its first argument (conventionally named 'self') and therefore
has no knowledge of the instance x.

> If I do that with an instance of generic 
> object however, I get an AttributeError. So:
> 
> x = object()
> x.fn = myFn
> 
> blows up. However, if I do
> 
> class nc(object):pass
> x = nc()
> x.fn = myFn
> 
> Then all is well.
> 
> checking for an ability on somebody is as simple as
> 
> 'fn' in dir(x)
> 
> or
> 
> hasattr(x, 'fn')
> 
> 
> I had thought this was a lot easier than I was making it out to be.
> What I don't know is why using an object derived from object allows
> you to dynamically add methods like this but the base object does not.
> At this point it is more of a curiosity than anything, but if somebody
> knows the answer off the top of their head, that would be great.

Arbitrary instance attributes are implemented via a dictionary (called
__dict__), and that incurs a certain overhead which is sometimes better to
avoid (think gazillion instances of some tiny class). For example, tuples
are derived from object but don't have a __dict__.
As a special case, what would happen if dict were to allow attributes? It
would need a __dict__ which would have a __dict__ which would have...
As a consequence object could no longer be the base class of all (newstyle)
classes.

Peter




More information about the Python-list mailing list