我有一个锅炉托盘类,它将一些操作委托给一个参考类。看起来是这样的:
class MyClass():
def __init__(self, someClass):
self.refClass = someClass
def action1(self):
self.refClass.action1()
def action2(self):
self.refClass.action2()
def action3(self):
self.refClass.action3()这是refClass:
class RefClass():
def __init__(self):
self.myClass = MyClass(self)
def action1(self):
#Stuff to execute action1
def action2(self):
#Stuff to execute action2
def action3(self):
#Stuff to execute action3我想使用来使它更加优雅和可读性,但我不确定如何做到这一点。
我听说过塞塔特和getattr,我想我可以这样做
class MyClass():
def __init__(self, someClass):
self.refClass = someClass
for action in ['action1', 'action2', 'action3']:
def _delegate(self):
getattr(self.refClass, action)()然后我知道我需要在某个地方做这件事,我想:
MyClass.setattr(action, delegate)我只是不能完全理解这个概念。我了解关于不重复代码和使用函数编程的for循环生成方法的基本知识,但是我不知道如何从其他地方调用这些方法。希尔普!
发布于 2015-09-28 17:44:50
Python已经包括了对包含类的广义委托的支持。只需将MyClass的定义更改为:
class MyClass:
def __init__(self, someClass):
self.refClass = someClass # Note: You call this someClass, but it's actually some object, not some class in your example
def __getattr__(self, name):
return getattr(self.refClass, name)定义时,当在实例本身上找不到属性时,都会使用访问属性的名称在实例上调用__getattr__。然后,通过调用getattr来查找包含的对象上的属性并返回该属性,从而将其委托给包含的对象。每次执行动态查找都要花费一点时间,因此如果您想要避免,可以在__getattr__第一次请求属性时延迟缓存它们,因此后续访问是直接的:
def __getattr__(self, name):
attr = getattr(self.refClass, name)
setattr(self, name, attr)
return attr发布于 2015-09-28 17:27:58
就我个人而言,我通常会做这样的事情:
def delegate(prop_name, meth_name):
def proxy(self, *args, **kwargs):
prop = getattr(self, prop_name)
meth = getattr(prop, meth_name)
return meth(*args, **kwargs)
return proxy
class MyClass(object):
def __init__(self, someClass):
self.refClass = someClass
action1 = delegate('refClass', 'action1')
action2 = delegate('refClass', 'action2')这将创建所需的所有委托方法:)
关于一些解释,这里的委托函数只是创建一个“代理”函数,它将充当类方法(请参阅self参数?)并将提供给它的所有参数通过args和kwargs参数传递给被引用对象的方法(有关这些参数的更多信息,请参见小矮人? )。
您也可以用一个列表来创建这个列表,但是我更喜欢第一个列表,因为它对我来说更明确:)
class MyClass(object):
delegated_methods = ['action1', 'action2']
def __init__(self, someClass):
self.refClass = someClass
for meth_name in self.delegated_methods:
setattr(self, meth_name, delegate('refClass', meth_name))https://stackoverflow.com/questions/32828305
复制相似问题