我正在编写一个用于编排 AWS 集群的小型框架,并且有一些反复出现的常见分层模式。一种这样的模式是将实例集合收集到一个更大的对象中,然后将一些方法直接委托给所有实例。因此,我没有一遍又一遍地复制和粘贴相同的样板代码,而是使用以下模式对其进行了抽象:
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
有没有更好的方式或模式来完成委托?
__getattr__
当遍历整个类层次结构并且没有找到该属性时调用。所以最好生成一次方法并将其存储在类中。那么下次找到方法就可以花更少的时间。
>>> 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>
在这里您可以看到代码的调整来做到这一点:
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']
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)