繁体   English   中英

在装饰器内扩展Python中的类

[英]Extending a class in Python inside a decorator

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

def useful_stuff(cls):
  class LocalClass(cls):
    def better_foo(self):
      print('better foo')
  return LocalClass

@useful_stuff
class MyClass:
  def foo(self):
    print('foo')

Unfortunaltely,MyClass的是不再与pickle由于非全球LocalClass

AttributeError: Can't pickle local object 'useful_stuff.<locals>.LocalClass'
  • 我需要挑选我的课程。 你能推荐一个更好的设计吗?
  • 考虑到类上可以有多个装饰器,通过让MyClass继承所有功能是一个更好的选择,可以切换到多重继承吗?

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

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

通过使用他们的模块和qualname来记录类,以记录在哪里找到类。 如果没有装饰,你的类需要在原始类所在的位置找到,因此pickle需要查看相同的模块和qualname。 这类似于funcutils.wraps对装饰函数的作用。

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

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

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

暂无
暂无

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

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