简体   繁体   English

Python:Pickle派生类,就好像它们是基类的实例一样

[英]Python: Pickle derived classes as if they were an instance of the base class

I want to define a base class so that when derived class instances are pickled, they are pickled as if they are instances of the base class. 我想定义一个基类,以便在派生类实例被pickle时,它们被腌制,好像它们是基类的实例一样。 This is because the derived classes may exist on the client side of the pickling but not on the server side, but this is not important to the server since it only needs information from the base class. 这是因为派生类可能存在于酸洗的客户端而不存在于服务器端,但这对服务器来说并不重要,因为它只需要来自基类的信息。 I don't want to have to dynamically create classes for every client. 我不想为每个客户端动态创建类。

The base class is simply an "object handle" which contains an ID, with methods defined on the server, but I would like the client to be able to subclass the server classes and define new methods (which would only be seen by the client, but that doesn't matter). 基类只是一个“对象句柄”,它包含一个ID,在服务器上定义了方法,但我希望客户端能够子类化服务器类并定义新方法(只能由客户端看到,但那没关系)。

I believe you can do it by giving the object a __reduce__ method, returning a tuple, the first part of which should be BaseClass.__new__ (this will be called when loading the object in unpickling). 相信你可以通过给对象一个__reduce__方法,返回一个元组来做到这一点,其中第一部分应该是BaseClass.__new__ (这将在unpickling中加载对象时调用)。 See the pickle documentation ( Python 2 , Python 3 ) for the full details. 有关详细信息,请参阅pickle文档( Python 2Python 3 )。 I haven't attempted this. 我没试过这个。

Depending on what you're doing, it might be easier to use a simpler serialisation format like JSON, and have code on each side to reconstruct the relevant objects. 根据您正在做的事情,使用更简单的序列化格式(如JSON)可能更容易,并且每侧都有代码来重建相关对象。

You can change an object's class dynamically in Python: 您可以在Python中动态更改对象的类:

import cPickle as pickle

class Foo(object):
    def __init__(self):
        self.id=1
class Bar(Foo):
    def derived_class_method(self): pass

bar=Bar()
bar.id=2
bar.__class__=Foo                # changes `bar`'s class to Foo
bar_pickled=pickle.dumps(bar)
bar2=pickle.loads(bar_pickled)
bar.__class__=Bar                # reset `bar`'s class to Bar
print(repr(bar2))
# <__main__.Foo object at 0xb76b08ec>
print(bar2.id)
# 2

I'm not sure using this is the best design decision, however. 但是,我不确定使用这是最好的设计决定。 I like Thomas K's idea of using JSON. 我喜欢Thomas K的使用JSON 的想法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM