在 Python 中创建 class 包装器

Creation of a class wrapper in Python

我想执行以下操作:给定一个 Base class 的实例,创建一个 Wrapper class 的对象,该对象具有所有方法和属性Base class + 一些附加功能。

class Base:

    def __init__(self, *args, **kwargs):
         self.base_param_1 = ...
         # some stuff

    def base_method_1(self, *args, **kwargs):
         # some stuff

class Wrapper(...):

    def  __init__(self, cls_instance, *args, **kwargs):
        self.wrapper_param_1 = ...
        # some stuff

    def wrapper_method_1(self, *args, **kwargs):
        # some stuff

用例如下:

wrapper_obj = Wrapper(Base(*base_args, **base_kwargs), *wrapper_args, *wrapper_kwargs)

预期的行为是可以访问 base_param_1, wrapper_param_1 并且 base_param_1, base_param_2.

重要的是 Base class 的字段在 Wrapper 中是相同的(没有复制)。

我看到可以通过这种方式添加新功能 Adding a Method to an Existing Object Instance,但这种方法有一些注意事项,不推荐使用。

继承在这里似乎不是一个选项,因为我是一个已经构建的对象,这个 Wrapper 可以采用不同的 classes,尽管有共同的 Base.

编辑

还要求Wrapper对象被识别为Base实例。

您可以覆盖 __getattr__。这样,首先查找 Wrapper 特定属性,然后尝试包装对象的属性。

class Wrapper:
    def  __init__(self, base_obj, *args, **kwargs):
        self.base_obj = base_obj
        # some stuff

    def wrapper_method(self):
        return "new stuff"

    def __getattr__(self, name):
        return getattr(self.base_obj, name)
        
w = Wrapper("abc")
w.wrapper_method()
# 'new stuff'
w.upper()
# 'ABC'

在@schwobaseggl 的帮助下,我想到了这个解决方案。可能有点疯狂,但具有所需的功能:

  class OuterWrapper:

    def __new__(self, obj, *args, **kwargs):

      class InnerWrapper:

        def __init__(self, obj, *args, **kwargs):
          self.obj = obj

        def __getattr__(self, name):
          return getattr(self.obj, name)

      wrapper_obj = InnerWrapper(obj, *args, **kwargs)
      InnerWrapper = type('InnerWrapper', (obj.__class__, InnerWrapper, object), {})
      wrapper_obj.__class__ = InnerWrapper
      return wrapper_obj