如何调用名称为字符串的对象的方法?

How to call a method of an object given by its name as string?

我有一个 python3 对象(class 实例),由

生成
myObj = myClass()

行。我还有一个 myMethodName 字符串:

myMethodName = "exampleName"

。如何调用由 myMethodName 命名的 myObj 的方法?因此,在这种情况下,我想调用 myObj.exampleName,它来自 getAttr(myObj, myMethodName).

不幸的是,python 文档(例如,here)引用的天真解决方案只给出了 KeyErrorAttributeError

由于 myObj 没有 method 方法而失败:

method = getAttr(myObj, myMethodName)
myObj.method(param)

这失败了,因为 myMethodName 有更多或更少的参数:

method = getAttr(myObj, myMethodName)
method(myObj, param)

简单调用

method = getAttr(myObj, myMethodName)
method(param)

这将是最合乎逻辑的,给出

TypeError: exampleName() takes 1 positional argument but 2 were given

那么,我该怎么做呢?

我使用 python 3.6,如果重要的话。


扩展:这是一个 MCVE:

class Test:
  name = None
  def __init__(name):
    self.name = name
  def process():
    method = getattr(self, 'process_' + name)
    method("param")
  def process_test(param):
    print ("process_test(): "+param)

test = Test("cica")
test.process("test")

导致第一个错误,因为getattrreturns一个方法已经绑定到对象实例(myObj)。

所以您所要做的就是调用您的 method 变量,就好像它是一个函数一样。

第二个错误可能是由于您的 exampleName 的参数数量与传递给 method 的参数数量不同。

对于第二个错误,您所要做的就是将相同的参数添加到 class:

中的方法中
myObj = myClass()class myClass:
    def exampleName(self, *args, **keyargs):
        print('Method exampleName was called')

myObj = myClass()

myMethodName = "exampleName"

method = getattr(myObj, myMethodName)
method('some param')

更新:

你添加的例子还有一些问题:

class Test:
    # This was removed, as you already initialize the instance variable in the constructor.
    # Setting it here would cause the variable to be shared by all instances of the class,
    # which you probably do not want, as you are passing the value as argument to the constructor below.
    # name = None

    # You missed to add the self parameter
    def __init__(self, name):
        self.name = name

    # Again, self parameter was missed
    # Additionally, we added a `suffix` parameter, that will accept the `test` value from the `process` call
    # We also added *args and **keyargs that will accept arbitrary number of parameters. Those will be
    # passed down to the `process_test` method.
    def process(self, suffix, *args, **keyargs):
        # We use the `suffix` parameter here, (instead of `name`)
        method = getattr(self, 'process_' + suffix)
        method(*args, **keyargs)

    def process_test(self, param):
        print("process_test(): " + param)


test = Test("cica")
test.process("test", "some param")

如果传递给 getattr() 的属性是一个方法名称,那么它 returns 一个已经绑定到对象的可调用对象:

getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

证明:

>>> x = [1, 2, 1, 3, 1, 1]
>>> f = getattr(x, 'count') # same as f = x.count
>>> f(1)
4

您的示例可以更改为以下内容:

class Test:
   def __init__(self, name):
       self.name = name
   def process(self, param):
       method = getattr(self, 'process_' + param)
       method("param")
   def process_test(self, param):
       print ("process_test(): "+param)


test = Test("cica")
test.process("test")

我认为您在 Python 中缺少 bound/static 方法的概念。看到这个 answer,它描述了不同类型的方法。