按名称调用 Python 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3521715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:32:35  来源:igfitidea点击:

Call a Python method by name

python

提问by Jazz

If I have an object and a method name in a string, how can I call the method?

如果我在字符串中有一个对象和一个方法名称,我该如何调用该方法?

class Foo:
    def bar1(self):
        print 1
    def bar2(self):
        print 2

def callMethod(o, name):
    ???

f = Foo()
callMethod(f, "bar1")

采纳答案by Enrico Carlesso

Use the built-in getattr()function:

使用内置getattr()函数:

class Foo:
    def bar1(self):
        print(1)
    def bar2(self):
        print(2)

def call_method(o, name):
    return getattr(o, name)()


f = Foo()
call_method(f, "bar1")  # prints 1

You can also use setattr()for setting class attributes by names.

您还可以setattr()用于按名称设置类属性。

回答by Bj?rn

getattr(globals()['Foo'](), 'bar1')()
getattr(globals()['Foo'](), 'bar2')()

No need to instantiate Foo first!

无需先实例化 Foo !

回答by Htechno

def callmethod(cls, mtd_name):    
    method = getattr(cls, mtd_name)
    method()

回答by Yaroslav Stavnichiy

I had similar question, wanted to call instance method by reference. Here are funny things I found:

我有类似的问题,想通过引用调用实例方法。以下是我发现的有趣的事情:

instance_of_foo=Foo()

method_ref=getattr(Foo, 'bar')
method_ref(instance_of_foo) # instance_of_foo becomes self

instance_method_ref=getattr(instance_of_foo, 'bar')
instance_method_ref() # instance_of_foo already bound into reference

Python is amazing!

蟒蛇太神奇了!

回答by Nitin Muppalaneni

Here is a more generalized version using Python decorators. You can call by short or long name. I found it useful when implementing CLI with short and long sub commands.

这是使用 Python 装饰器的更通用版本。您可以按短名称或长名称呼叫。我发现在使用短和长子命令实现 CLI 时它很有用。

Python decorators are wonderful. Bruce Eckel (Thinking in Java) describes Python decorators beautifully here.

Python 装饰器很棒。Bruce Eckel(Thinking in Java)在这里很好地描述了 Python 装饰器。

http://www.artima.com/weblogs/viewpost.jsp?thread=240808http://www.artima.com/weblogs/viewpost.jsp?thread=240845

http://www.artima.com/weblogs/viewpost.jsp?thread=240808 http://www.artima.com/weblogs/viewpost.jsp?thread=240845

#!/usr/bin/env python2

from functools import wraps


class CommandInfo(object):
    cmds = []

    def __init__(self, shortname, longname, func):
        self.shortname = shortname
        self.longname = longname
        self.func = func


class CommandDispatch(object):
    def __init__(self, shortname, longname):
        self.shortname = shortname
        self.longname = longname

    def __call__(self, func):
        print("hello from CommandDispatch's __call__")

        @wraps(func)
        def wrapped_func(wself, *args, **kwargs):
            print('hello from wrapped_func, args:{0}, kwargs: {1}'.format(args, kwargs))
            func(wself, *args, **kwargs)

        ci = CommandInfo
        ci.cmds += [ci(shortname=self.shortname, longname=self.longname, func=func)]
        return wrapped_func

    @staticmethod
    def func(name):
        print('hello from CommandDispatch.func')

        for ci in CommandInfo.cmds:
            if ci.shortname == name or ci.longname == name:
                return ci.func

        raise RuntimeError('unknown command')


@CommandDispatch(shortname='co', longname='commit')
def commit(msg):
    print('commit msg: {}'.format(msg))


commit('sample commit msg')         # Normal call by function name

cd = CommandDispatch
short_f = cd.func(name='co')        # Call by shortname
short_f('short sample commit msg')

long_f = cd.func(name='commit')     # Call by longname
long_f('long sample commit msg')


class A(object):
    @CommandDispatch(shortname='Aa', longname='classAmethoda')
    def a(self, msg):
        print('A.a called, msg: {}'.format(msg))


a = A()
short_fA = cd.func(name='Aa')
short_fA(a, 'short A.a msg')

long_fA = cd.func(name='classAmethoda')
long_fA(a, 'short A.a msg')