在 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
我想执行以下操作:给定一个 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