dynamic class definition

Jeff P. Lankford (jpl@nrtc.northrop.com)
Thu, 1 Sep 1994 18:23:33 GMT

There is an interesting capability of Python classes not well documented.
I want to exploit this feature, and i would like to be forewarned of
any pitfalls.

The following module was tested.
#!/usr/local/bin/python

class fu:
x = 7
def bar():
print x
def sna():
pass
print 'fu', fu.__name__, fu.__dict__

i = fu()
print 'i', i.__dict__, i.x

setattr(fu, 'fudge', 9)
print 'fu', fu.__name__, fu.__dict__
print 'i', i.__dict__, i.x, i.fudge

def barf(self, x):
print x

setattr(fu, 'swag', barf)
print 'fu', fu.__name__, fu.__dict__
print 'i', i.__dict__, i.x, i.swag(42)

It generated the following output.

fu fu {'x': 7, 'sna': <function sna at 9ac18>, 'bar': <function bar at 9abf8>}
i {} 7
fu fu {'fudge': 9, 'x': 7, 'sna': <function sna at 9ac18>, 'bar': <function bar at 9abf8>}
i {} 7 9
fu fu {'fudge': 9, 'x': 7, 'sna': <function sna at 9ac18>, 'bar': <function bar at 9abf8>, 'swag': <function barf at 92110>}
i {} 7 42
None

[I'm not sure exactly were the 'None' came from, but it's not germane.]
Note that after adding both a data attribute and a method attribute to
the class namespace, BOTH the class AND the previously instantiated instance
had access to the updated namespace. One capability i want is clearly
available, ie to modify a class namespace subsequent to definition. However,
i was surprised that old instances would see the new definition. This is
i suppose a consequence of the instance having a pointer to the definition,
rather than a copy of the definition. I can conceive circumstances where
this behaviour is desirable, and others where it is intolerable. One might
make the claim, for example, that the ability to modify class definitions
betters supports program reusability than nesting class wrappers via
inheritance.

The question is: although this behavior is not documented (as far as i know),
is this aspect of the implementation subject to change? E-mail me directly,
and i will summarize for the group.

thanks,
jpl