如何将类装饰器与泡菜一起使用? [英] How to use class decorators with pickle?

查看:89
本文介绍了如何将类装饰器与泡菜一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我想使用类装饰器(而不是函数装饰器!)

I would like to use class decorators (not function decorators!), e.g.

def class_decorator(cls):
    class new_cls(cls):
        def run(self, *args, **kwargs):
            print 'In decorator'
            super(new_cls,self).run(*args, **kwargs)
    return new_cls

@class_decorator
class cls(object):
    '''
    a class
    '''
    def run(self):
        print 'called'

并能够腌制对象:

import pickle

a = cls()
a.run()
s = pickle.dumps(a)

但是,泡菜返回错误:

PicklingError: Can't pickle <class '__main__.new_cls'>: it's not found as __main__.new_cls

任何帮助将不胜感激!

推荐答案

当您腌制课程时,

When you pickle a class, the name of the class -- not its value -- is pickled. If the class_decorator returns a new class whose name is not defined at the top level of the module, then you get the error:

PicklingError: Can't pickle <class '__main__.new_cls'>: it's not found as __main__.new_cls 

通过将新装饰的类命名为未装饰的类,可以避免错误:

You can avoid the error by naming the new decorated class the same as the undecorated class:

new_cls.__name__ = cls.__name__

然后代码运行没有错误:

Then the code runs without error:

import pickle

def class_decorator(cls):
    class new_cls(cls):
        def run(self, *args, **kwargs):
            print 'In decorator'
            super(new_cls,self).run(*args, **kwargs)
    new_cls.__name__ = cls.__name__
    return new_cls

@class_decorator
class cls(object):
    def run(self):
        print 'called'

a = cls()
print(a)
# <__main__.cls object at 0x7f57d3743650>

a.run()
# In decorator
# called

s = pickle.dumps(a)
# Note "cls" in the `repr(s)` below refers to the name of the class. This is
# what `pickle.loads` is using to unpickle the string
print(repr(s))
# 'ccopy_reg\n_reconstructor\np0\n(c__main__\ncls\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n.'

b = pickle.loads(s)
print(b)
# <__main__.cls object at 0x7f57d3743690>

b.run()
# In decorator
# called

这篇关于如何将类装饰器与泡菜一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆