python中的方法委托 [英] Method delegation in python

查看:45
本文介绍了python中的方法委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个用于编排 AWS 集群的小型框架,并且有一些常见的层次结构模式反复出现.一种这样的模式是将一组实例收集到一个更大的对象中,然后将一些方法直接委托给所有实例.因此,我没有一遍又一遍地复制和粘贴相同的样板代码,而是使用以下模式对其进行了抽象:

def __getattr__(self, item):如果不是 self._allowed_items 中的项目:引发 NonDelegatableItem定义委托人():例如在 self.all_instances 中:getattr(实例,项目)()返回委托人

是否有更好的方式或模式来完成委托?

解决方案

__getattr__ 在遍历整个类层次结构并且找不到属性时调用.所以最好是生成一次方法并将其存储在类中.然后下次找到方法花费更少的时间.

<预><代码>>>>X.a回溯(最近一次调用最后一次):文件<pyshell#15>",第 1 行,在 <module> 中X.aAttributeError: 类 X 没有属性a">>>x.a新委托人<0x02937D30处的函数委托人>>>>x.a<在0x028DBC60处<__main__.X实例的绑定方法X.delegator>>>>>X.a<未绑定方法X.delegator>

在这里你可以看到你的代码为做到这一点所做的调整:

class NonDelegatableItem(AttributeError):经过X级:def __getattr__(self, method_name):self.check_method_name_is_delegator(method_name)返回 self.create_delegator(method_name)def check_method_name_is_delegator(self, method_name):如果 method_name 不在 self._allowed_items 中:raise NonDelegatableItem('{} 不能被委托'.format(method_name))@类方法def create_delegator(cls, method_name):打印新委托人"def 委托人(self, *args, **kw):self.check_method_name_is_delegator(method_name)例如在 self.all_instances 中:getattr(instance, method_name)(*args, **kw)setattr(cls,method_name,委托人)返回委托人x = X()x._allowed_items = ['a', 'b']

I'm writing a small framework for orchestrating AWS clusters and there are some common hierarchical patterns that appear over and over again. One such pattern is gathering a collection of instances into a bigger object and then delegating some methods down to all the instances directly. So instead of copying and pasting the same boilerplate code over and over again I abstracted it with the following pattern:

def __getattr__(self, item):
    if not item in self._allowed_items:
        raise NonDelegatableItem

    def delegator():
        for instance in self.all_instances:
            getattr(instance, item)()

    return delegator

Is there a better way or pattern for accomplishing the delegation?

解决方案

__getattr__ is called when the whole class hirarchy is traversed and the attribute is not found. So it is better to generate the method once and store it in the class. Then finding the method takes less time next time.

>>> X.a

Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    X.a
AttributeError: class X has no attribute 'a'
>>> x.a
new delegator
<function delegator at 0x02937D30>
>>> x.a
<bound method X.delegator of <__main__.X instance at 0x028DBC60>>
>>> X.a
<unbound method X.delegator>

Here you can see the adaption of your code to do that:

class NonDelegatableItem(AttributeError):
    pass

class X:
    def __getattr__(self, method_name):
        self.check_method_name_is_delegator(method_name)
        return self.create_delegator(method_name)

    def check_method_name_is_delegator(self, method_name):
        if method_name not in self._allowed_items:
            raise NonDelegatableItem('{} can not be delegated'.format(method_name))

    @classmethod
    def create_delegator(cls, method_name):
        print 'new delegator'
        def delegator(self, *args, **kw):
            self.check_method_name_is_delegator(method_name)
            for instance in self.all_instances:
                getattr(instance, method_name)(*args, **kw)
        setattr(cls, method_name, delegator)
        return delegator


x = X()

x._allowed_items = ['a', 'b']

这篇关于python中的方法委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆