我希望在Python中实现转发类,实现一些基类,它在构造函数中接受同一基类的另一个实现,并为基类中的每个方法转发到该类。
这对于提供自定义点,为某些方法添加缓存,在每个调用站点中记录等等非常有用。
手动编写此内容非常简单。鉴于此基类:
class BaseClass(object):
def method_a(self, *args):
pass
@property
def prop_b(self):
pass
def method_c(self, a, b, **kwargs):
pass
这是一个简单的转发实施。
class ForwardBaseClass(BaseClass):
def __init__(self, underlying_implementation):
self._impl = underlying_implementation
def method_a(self, *args):
return self._impl.method_a(*args)
@property
def prop_b(self):
return self._impl.prop_b
def method_c(self, a, b, **kwargs):
return self._impl.method_c(a, b, **kwargs)
编写代码的缺点是有很多样板代码,并且必须为每个方法编写代码。随着方法被添加到基类中,类似的代码必须被添加到转发类中;如果需要对类的转发方式进行更改,则必须通过所有方法进行传播。 (例如,想象一下,我们想要更改类,以便它在每次调用时都使用了一个上下文管理器。)
是否有一种简短的Pythonic方式,无论是基本语言,内置模块还是PyPI上的一些可靠模块?
所需功能:
*args, **kwargs
@property
装饰器的方法__<method>__
方法(如果存在)正确包装dir(instance)
与直接实施完全相同很高兴:
@staticmethod
装饰器的方法转发到传入实现的类@classmethod
装饰器的方法转发到传入实现的类__init__
和__new__
未转发可能存在额外复杂性的地方:
__<method>__
及其语义不要真心关心:
@property
,@staticmethod
和@classmethod
答案 0 :(得分:0)
只是为了澄清我的评论:我的意思是+/-这个(虽然需要更多工作......再次:可能无法满足您的所有要求):
class BaseClass(object):
def method_a(self, *args):
pass
@property
def prop_b(self):
pass
def method_c(self, a, b, **kwargs):
pass
class ForwardBaseClass(BaseClass):
def __init__(self, underlying_implementation):
self._impl = underlying_implementation
def __getattr__(self, name):
# here you may have to exclude thigs; i.e. forward them to
# self.name instead for self._impl.name
try:
return getattr(self._impl, name)
except AttributeError:
# do something else...
bc = BaseClass()
fbc = ForwardBaseClass(bc)
print(fbc.prop_b)
print(fbc.method_c(1,2,c=5))
print(dir(fbc))
请注意,由于python name mangling,您将无法以__
这种方式访问成员。