Changing an object's class
Gerald Klix
Gerald.Klix at klix.ch
Mon May 26 10:35:15 EDT 2003
Perhaps a small code snippet from 2.3a2 pickle module may give you some
hint:
def _instantiate(self, klass, k):
args = tuple(self.stack[k+1:])
del self.stack[k:]
instantiated = 0
if (not args and
type(klass) is ClassType and
not hasattr(klass, "__getinitargs__")):
try:
value = _EmptyClass()
value.__class__ = klass
instantiated = 1
except RuntimeError:
# In restricted execution, assignment to inst.__class__ is
# prohibited
pass
if not instantiated:
try:
value = klass(*args)
except TypeError, err:
raise TypeError, "in constructor for %s: %s" % (
klass.__name__, str(err)), sys.exc_info()[2]
self.append(value)
I would say: You are in good (or bad) company with your solution.
HTH,
Gerald
marshall wrote:
> I am building a simple GUI and I want to determine the layout of
> objects at runtime. So I have stored the objects as a dictionary of
> elements each of which is a dictionary of attributes including the
> type. Each type is a class. I could query the type on load and
> create each instance and load its attributes. But instead I used an
> empty class and then changed it based on the type. [I'm sure there is
> a comp sci name for this like meta-generator-abstract-whatnot - I call
> it a Doppelganger.]
>
> class cDoppel:
> def __init__(self,kw):
> self.__dict__ = kw
> self.__class__ = eval(kw['class'])
>
> class cHalfBee:
> pass
>
> class cPoofta:
> pass
>
> class cContainer:
> def __init__(self,elements):
> for element in elements.items():
> name, attributes = element
> self.__dict__[name] = cDoppel(attributes)
>
> #Test
> elements = {'Eric':{'class':'cHalfBee','attribA':(1,2),'attribB':25},'Bruce':{'class':'cPoofta','ears':2}}
> bag = cContainer(elements)
> print 'Bag has',dir(bag)
> print 'Eric has',dir(bag.Eric)
> print 'Eric is a ' + str(bag.Eric)
>
> Output:
> Bag has ['Bruce', 'Eric', '__doc__', '__init__', '__module__']
> Eric has ['__doc__', '__module__', 'attribA', 'attribB', 'class']
> Eric is a <__main__.cHalfBee instance at 0x00C58BF0>
>
> I like the results and might use this technique elsewhere.
>
> Questions:
> Is this naughty or nice? Why?
> Google shows some old, olympian discussion of locking down __class__
> but I did not see a resolution of it. Will this be a mortal or a
> venal sin?
>
> Thanks,
> Marshall
More information about the Python-list
mailing list