是否有#34;通配符方法"在Python?

时间:2016-04-12 13:29:31

标签: python class methods

我正在寻找一种方法来使用一个类的方法,该方法没有在该类中定义,但是动态处理。举个例子,我想要实现的是从

移动
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

可以在类中使用aaabbb(和其他),而无需明确定义它们。对于上面的示例,它将是一个构造,它接收所使用的方法的名称(例如aaa)并相应地格式化消息。

换句话说,一个"通配符方法"它本身将处理其名称并根据名称执行条件操作。在伪代码中(复制上面的例子)

def *wildcard*(self, msg=""):
    method = __name__which__was__used__to__call__me__
    print("{msg} {method}".format(msg=msg, method=method))

这样的建筑可能吗?

3 个答案:

答案 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