pickling instances of metaclass generated classes

Peter Otten __peter__ at web.de
Sun Jan 1 07:51:05 EST 2012


lars van gemerden wrote:

>> import pickle
>> import sys
>>
>> class MetaClass(type):
>>     pass
>>
>> class M(object):
>>     def __init__(self, module):
>>         self.__module = module
>>     def __getattr__(self, name):
>>             print "creating class", name
>>             class_ = MetaClass(name, (), {"__module__": self.__module})
>>             setattr(self, name, class_)
>>             return class_
>>
>> sys.modules["m"] = M("m")
>> import m
>> c = m.x
>> s = pickle.dumps(c)
>> print repr(s)
>> d = pickle.loads(s)
>>
>> assert c is d
>>
>> sys.modules["m"] = M("m")
>> e = pickle.loads(s)
>>
>> assert c is not e
>>
>> The official way is probably what Robert mentioned, via the copy_reg
>> module, but I didn't get it to work.
> 
> I will look further into this. does "sys.modules["m"] = M("m")" create
> a new module?

Assigning to sys.modules[modulename] can put arbitrary objects into the 
module cache, in this case an M instance. To drive the point home:

>>> import sys
>>> sys.modules["x"] = 42
>>> import x
>>> x
42
>>> sys.modules["x"] = "spam"
>>> import x
>>> x
'spam'

> Cheers, Lars
> 
> PS: I get an error when posting this to the usenet group

Sorry, that seems to happen when I post via gmane and don't manually clear 
the follow-up that my newsreader helpfully (knode) inserts. I've not yet 
found a permanent fix, but if that was the problem you should be able to 
answer this post.




More information about the Python-list mailing list