Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
泡菜不';t在Python2.6上不考虑我注册的自定义类型reduce函数_Python_Pickle_Python 2.6 - Fatal编程技术网

泡菜不';t在Python2.6上不考虑我注册的自定义类型reduce函数

泡菜不';t在Python2.6上不考虑我注册的自定义类型reduce函数,python,pickle,python-2.6,Python,Pickle,Python 2.6,给定以下代码: 导入pickle 导入副本 A类(类型): 通过 B类(对象): __元类\uuua=A def _reduce_a(a): 打印('嘿,那里') 返回一个名称__ 复制\u reg.pickle(A,\u reduce\u A) 泡菜倾倒区(B) 在Python2.6上尝试pickleB时,注册的\u reduce\u a函数从未被调用,后者是a实例,但在2.7上被调用 这是一个已知的错误吗?我认为这是一个2.6错误/限制。您可以看到,如果调用copy.copy(B),您的函

给定以下代码:

导入pickle
导入副本
A类(类型):
通过
B类(对象):
__元类\uuua=A
def _reduce_a(a):
打印('嘿,那里')
返回一个名称__
复制\u reg.pickle(A,\u reduce\u A)
泡菜倾倒区(B)
在Python2.6上尝试pickle
B
时,注册的
\u reduce\u a
函数从未被调用,后者是
a
实例,但在2.7上被调用


这是一个已知的错误吗?

我认为这是一个2.6错误/限制。您可以看到,如果调用
copy.copy(B)
,您的函数将被调用,但当调用
pickle.dumps(B)
时,函数不会被调用。Python 2.7.3中添加了一个新特性,允许动态创建类被pickle。见:

目前,即使用户通过copy_reg请求不同的pickle机制,也不可能使用常用的pickle机制来pickle动态创建的类。附加的补丁通过简单地转置两块代码就可以实现这种定制

copy_reg模块用于处理对象的自定义酸洗,这正是此处需要的。但是,检查元类实例的代码在查看copy_reg dispatch表之前执行此操作。修补程序只是在pickle.py和cPickle.c中对这些测试重新排序,这样就可以为元类的实例注册自定义pickler

从以下方面:

问题#7689:当动态创建的类的元类注册到copy#u reg时,允许对其进行酸洗。Nicolas M.Thiéry和Craig Citro的补丁

Python2.6解决这个问题的唯一方法是将
pickle.py
模块移植到该版本。您可以尝试将2.7.3
pickle.py
模块与2.6捆绑在一起,作为一个纯Python实现,它应该可以正常工作

或者,对
pickle.Pickler.save
方法进行猴子补丁:

from copy_reg import dispatch_table
from types import TypeType, StringType, TupleType
from pickle import Pickler, PicklingError


def pickler_save(self, obj):
    # Check for persistent id (defined by a subclass)
    pid = self.persistent_id(obj)
    if pid:
        self.save_pers(pid)
        return

    # Check the memo
    x = self.memo.get(id(obj))
    if x:
        self.write(self.get(x[0]))
        return

    # Check the type dispatch table
    t = type(obj)
    f = self.dispatch.get(t)
    if f:
        f(self, obj) # Call unbound method with explicit self
        return

    # Check copy_reg.dispatch_table
    reduce = dispatch_table.get(t)
    if reduce:
        rv = reduce(obj)
    else:
        # Check for a class with a custom metaclass; treat as regular class
        try:
            issc = issubclass(t, TypeType)
        except TypeError: # t is not a class (old Boost; see SF #502085)
            issc = 0
        if issc:
            self.save_global(obj)
            return

        # Check for a __reduce_ex__ method, fall back to __reduce__
        reduce = getattr(obj, "__reduce_ex__", None)
        if reduce:
            rv = reduce(self.proto)
        else:
            reduce = getattr(obj, "__reduce__", None)
            if reduce:
                rv = reduce()
            else:
                raise PicklingError("Can't pickle %r object: %r" %
                                    (t.__name__, obj))

    # Check for string returned by reduce(), meaning "save as global"
    if type(rv) is StringType:
        self.save_global(obj, rv)
        return

    # Assert that reduce() returned a tuple
    if type(rv) is not TupleType:
        raise PicklingError("%s must return string or tuple" % reduce)

    # Assert that it returned an appropriately sized tuple
    l = len(rv)
    if not (2 <= l <= 5):
        raise PicklingError("Tuple returned by %s must have "
                            "two to five elements" % reduce)

    # Save the reduce() output and finally memoize the object
    self.save_reduce(obj=obj, *rv)


Pickler.save = pickler_save

这是在Python2.6还是2.7上?标签上写着2.6,你的问题上写着2.7。我已经更新了我的问题。
\u reduce\u a
函数在2.7中被调用,但在2.6中没有调用。您知道公开pickle/unpickle函数的其他方法吗?我试着在
a
上声明
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法,但从未调用过。
>>> pickle.dumps(B)
Hey there
'c__main__\nB\np0\n.'