在装饰器中扩展Python中的类

时间:2018-12-16 17:39:54

标签: python python-3.x pickle python-decorators

我正在使用装饰器扩展某些类并向其添加一些功能,如下所示:

AttributeError: Can't pickle local object 'useful_stuff.<locals>.LocalClass'

不幸的是,由于非全局 LocalClass

MyClass 不再pickleable
{{1}}
  • 我需要给我的课上泡菜。您能推荐一个更好的设计吗?
  • 考虑到一个类上可以有多个装饰器,让 MyClass 继承所有功能会切换到多重继承吗?

1 个答案:

答案 0 :(得分:8)

您需要设置元数据,以便子类看起来像原始的:

def deco(cls):
    class SubClass(cls):
        ...
    SubClass.__name__ = cls.__name__
    SubClass.__qualname__ = cls.__qualname__
    SubClass.__module__ = cls.__module__
    return SubClass

使用类的模块和质量名对类进行腌制,以记录在何处可以找到该类。如果您的班级没有经过修饰,则需要在与原班级相同的位置找到它,因此,pickle需要看到相同的模块和名称。这类似于funcutils.wraps对修饰函数所做的操作。

但是,将新方法直接添加到原始类而不是创建子类可能更简单,更不易出错:

def better_foo(self):
    print('better_foo')

def useful_stuff(cls):
    cls.better_foo = better_foo
    return cls