我正在寻找一种方法来使用一个类的方法,该方法没有在该类中定义,但是动态处理。举个例子,我想要实现的是从
移动class Hello:
def aaa(self, msg=""):
print("{msg} aaa".format(msg=msg))
def bbb(self, msg=""):
print("{msg} bbb".format(msg=msg))
if __name__ == "__main__":
h = Hello()
h.aaa("hello")
h.bbb("hello")
# hello aaa
# hello bbb
可以在类中使用aaa
和bbb
(和其他),而无需明确定义它们。对于上面的示例,它将是一个构造,它接收所使用的方法的名称(例如aaa
)并相应地格式化消息。
换句话说,一个"通配符方法"它本身将处理其名称并根据名称执行条件操作。在伪代码中(复制上面的例子)
def *wildcard*(self, msg=""):
method = __name__which__was__used__to__call__me__
print("{msg} {method}".format(msg=msg, method=method))
这样的建筑可能吗?
答案 0 :(得分:10)
您可以重载类“__getattr__
方法:
class Hello:
def __getattr__(self, name):
def f(msg=""):
print("{} {}".format(msg, name))
return f
if __name__ == "__main__":
h = Hello()
h.aaa("hello")
h.bbb("hello")
结果:
hello aaa
hello bbb
答案 1 :(得分:0)
如果您事先知道方法的名称,可以使用为您添加所有方法的装饰器来完成此操作。
from functools import partial
def glue(f, names=[]):
def wrapper(cls):
method = getattr(cls,f)
for name in names:
setattr(cls, name, partial(method,name=name))
return cls
return wrapper
像这样使用:
@glue(f = 'wildcard', names = ['aaa', 'bbb'])
class Hello():
def wildcard(self, msg='', name=''):
print("{} {}".format(msg, name))
如果您不熟悉装饰器,上面的@
语法相当于在类定义后执行此操作:
Hello = glue(f = 'wildcard', names = ['aaa', 'bbb'])(Hello)
答案 2 :(得分:0)
我发现上面的答案有点难以理解,所以我做到了。
受Django代码启发。
class MyClass:
def __init__(self, **kwargs):
for arg in ('aaa', 'bbb'):
# generate a new function based on the template function.
setattr(self, f'make_{arg}', partialmethod(self._make_ARG, arg=arg))
def _make_ARG(self, arg, **kwargs):
value = getattr(self, arg)
# override make_{ARG} function to generate an argument based on codex.
return value