On Jan 1, 5:59 pm, Josh English <joshua.r.engl...@gmail.com> wrote: > I have hit yet another wall. I am dynamically creating a class and then > creating instances of that class. The class relies on a second class to store > a list of objects. (This is simplified from the the original by a factor of > about 20. The real program is trying to create a Python object around an XML > definition object.) > > Here's the code: > > ## OPTION ONE for class: ElementList > ### Not really a list, but a wrapper that behaves like a list > class ElementList(object): > def __init__(self, parent, name): > self._parent = parent > self._name = name > > def MakeWrapper(checker, _addNameAsAttribute = False ): > > ## OPTION TWO for class: ElementList > class Wrap(object): > > ## OPTION THREE for class: Elementlist > > def __init__(self, name): > self._name = name > setattr(Wrap, 'stuff', ElementList(self, 'test')) > > Wrap.__name__= checker.title() > > return Wrap > > if __name__ == '__main__': > > Dude = MakeWrapper('Dude') > print Dude > d1 = Dude('Josh') > print d1, d1.stuff > > # creating the second instance changes the behavior of the subclass > d2 = Dude('Ben') > print d2, d2.stuff > print d1.stuff._parent > print d2.stuff._parent > > #creating a third instance changes the behavior of all the subclasses > d3 = Dude('David') > print d3, d3.stuff > print d1.stuff._parent, d2.stuff._parent, d3.stuff._parent > > ## END CODE > > And here is the output: > > > > <class '__main__.Dude'> > <__main__.Dude object at 0x00DFB930> <__main__.ElementList object at > 0x00DFB950> > <__main__.Dude object at 0x00DFB730> <__main__.ElementList object at > 0x00DFB770> > <__main__.Dude object at 0x00DFB730> > <__main__.Dude object at 0x00DFB730> > <__main__.Dude object at 0x00DFB870> <__main__.ElementList object at > 0x00DFB9B0> > <__main__.Dude object at 0x00DFB870> <__main__.Dude object at 0x00DFB870> > <__main__.Dude object at 0x00DFB870> > > The 'stuff' attribute is an ElementList object linked back to the parent > instance, but every time I create an instance, every instance's 'stuff' links > back to the last instance created. >
If every instance's <whatever> is the same, one guesses that the <whatever> has a class scope, rather than an instance scope. > I'm not sure why this is happening, or how to prevent it. > It's perfectly predictable; to understand what is happening, compare: >>> def foo(): class Bar(object): def __init__(self): setattr(Bar, 'stuff', {}) return Bar >>> Dude = foo() >>> a = Dude() >>> b = Dude() >>> a.stuff['foo'] = 2 >>> b.stuff {'foo': 2} >>> c = Dude() >>> a.stuff {} with the behavior (which I think you expected) of: >>> def foo(): class Bar(object): def __init__(self): setattr(self, 'stuff', {}) return Bar >>> Dude = foo() >>> a = Dude() >>> b = Dude() >>> a.stuff['foo'] = 2 >>> b.stuff {} >>> c = Dude() >>> a.stuff {'foo': 2} Cheers - Chas -- http://mail.python.org/mailman/listinfo/python-list