zap*_*lla 5 python metaprogramming dry setattr getattr
我有一个boiler platey类,它将一些操作委托给引用类.它看起来像这样:
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()
Run Code Online (Sandbox Code Playgroud)
这是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
Run Code Online (Sandbox Code Playgroud)
我想使用Python Metaprogramming使这更优雅和可读,但我不知道如何.
我听说过setattr和getattr,我想我可以做类似的事情
class MyClass():
def __init__(self, someClass):
self.refClass = someClass
for action in ['action1', 'action2', 'action3']:
def _delegate(self):
getattr(self.refClass, action)()
Run Code Online (Sandbox Code Playgroud)
然后我知道我需要从某个地方做这个,我想:
MyClass.setattr(action, delegate)
Run Code Online (Sandbox Code Playgroud)
我无法完全掌握这个概念.我理解不重复代码的基础知识,并使用带有函数编程的for循环生成方法,但后来我不知道如何从其他地方调用这些方法.Heeeelp!
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)
Run Code Online (Sandbox Code Playgroud)
定义时,__getattr__
只要在实例本身找不到属性,就会在具有被访问属性名称的实例上调用.然后通过调用getattr
查找包含的对象上的属性并返回它来委托包含的对象.每次进行动态查找都会花费很少,所以如果你想避免它,你可以在第一次请求时懒得缓存属性__getattr__
,因此后续访问是直接的:
def __getattr__(self, name):
attr = getattr(self.refClass, name)
setattr(self, name, attr)
return attr
Run Code Online (Sandbox Code Playgroud)