簡體   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