如何调用名称为字符串的对象的方法?
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)引用的天真解决方案只给出了 KeyError
或 AttributeError
。
由于 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")
导致第一个错误,因为getattr
returns一个方法已经绑定到对象实例(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,它描述了不同类型的方法。
我有一个 python3 对象(class 实例),由
生成myObj = myClass()
行。我还有一个 myMethodName
字符串:
myMethodName = "exampleName"
。如何调用由 myMethodName
命名的 myObj
的方法?因此,在这种情况下,我想调用 myObj.exampleName
,它来自 getAttr(myObj, myMethodName)
.
不幸的是,python 文档(例如,here)引用的天真解决方案只给出了 KeyError
或 AttributeError
。
由于 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")
导致第一个错误,因为getattr
returns一个方法已经绑定到对象实例(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 theobject
’s attributes, the result is the value of that attribute. For example,getattr(x, 'foobar')
is equivalent tox.foobar
. If the named attribute does not exist,default
is returned if provided, otherwiseAttributeError
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,它描述了不同类型的方法。