加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python中最简单的转发类定义是什么?

发布时间:2020-12-20 13:06:30 所属栏目:Python 来源:网络整理
导读:我想在 Python中实现一个转发类,实现一些基类,它在构造函数中接受同一基类的另一个实现,并为基类中的每个方法转发到该类. 这对于提供定制点,添加特定方法的高速缓存,记录每个调用站点等是有用的. 手动编写它很简单.鉴于此基类: class BaseClass(object): de
我想在 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,**kwargs):
        return self._impl.method_c(a,**kwargs)

编写代码的缺点是有很多样板代码,并且必须为每个方法编写代码.随着方法被添加到基类中,类似的代码必须被添加到转发类中;如果需要对类的转发方式进行更改,则必须通过所有方法进行传播. (想象一下,例如,我们想要更改类,以便它在每次调用时使用了一个上下文管理器.)

有没有一种简短的Pythonic方法,无论是基本语言,内置模块,还是PyPI上的一些可靠模块?

所需功能:

>精确方法签名

>转发的签名应与基类匹配
>没有* args,**每个签名都有kwargs

>正确包装@property装饰器的方法
> __< method> __方法(如果存在)被正确包装
>对于直接实现,每个方法调用不需要额外的成本
> dir(instance)与直接实现完全相同

很高兴有:

>基类不符合某些必要条件的错误消息
>有意义的docstrings
>能够从结果对象派生
>使用@staticmethod装饰器的方法被转发到传入实现的类
>使用@classmethod装饰器的方法被转发到传入实现的类
> __init__和__new__不会转发

可能存在额外复杂性的地方:

>基类有一个元类
>基类有自己的多个基类
>一些更深奥的__< method> __ s及其语义

不关心:

>多个基类
> @property,@ staticmethod和@classmethod以外的自定义描述符装饰器
>转发类创建后对基类的修改

解决方法

只是为了澄清我的评论:我的意思是/ – 这(虽然需要更多工作……再次:可能无法满足您的所有要求):

class BaseClass(object):
    def method_a(self,**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,您将无法以这种方式访问??以__开头的成员.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读