通过字符串调用函数
Calling function through string
我有一个 Python 主程序,它导入另一个具有多个功能的模块(称为动作)。主程序应该运行一些东西,得到一个字符串(即goto(114))然后运行 actions.goto(114),其中114是函数goto( x) 在行动中。
我已经尝试了明显的尝试 运行 字符串,但是没有用。我还找到了 globals() 方法,如果 goto(x) 在我的主模块中,它会起作用,我还找到了 getattr 方法,但在这种情况下,我还没有找到我传递函数名称和争论所以我有点迷路了。
#main.py
import actions
def main():
getc = 'goto(114)'
result = actions.getc #this would be actions.goto(114)
print result
#actions.py
def goto(x):
#code
return something
实际程序从另一个程序编写的.txt文件中获取字符串,我只是这样制作示例以便于理解。
您可以使用的一个选项是 action
class 上的 __getattribute__
来获取函数 goto
,然后使用包含的参数调用它。您需要像这样解析它:
import re
import action
getc = 'goto(114)'
func, arg = re.search('(\w+)\((\d+)\)', 'goto(114)').groups()
# f is the function action.goto with the argument 114 supplied as an int
# __getattribute__ allows you to look up a class method by a string name
f = action.__getattribute__(func)
# now you can just call it with the arg converted to int
result = f(int(arg))
正则表达式可能需要改进一下,但它正在查找调用函数的名称以及括在括号中的参数。 __getattribute__
将从 action
和 return 中获取函数对象,它未被调用,因此您可以稍后调用它。
对于多个参数,您可以利用 ast
库:
import re
import ast
# I'm going to use a sample class as a stand-in
# for action
class action:
def goto(*args):
print(args)
getc = 'goto(114, "abc", [1,2,3])'
func, args = re.search('(\w+)\((.*)\)', getc).groups()
# will convert this into python data structures
# safely, and will fail if the argument to literal_eval
# is not a python structure
args = ast.literal_eval('(%s)' % args)
f = getattr(action, func)
f(*args)
# 114, "abc", [1,2,3]
更简单的选择(谨慎行事)是使用 eval
:
cmd = 'action.%s' % getc
result = eval(cmd)
请注意,尽管标准库中有使用它的示例,但在 python 社区中这被认为是不好的做法。这对 un-validated 代码来说是不安全的,如果您不监视源文件
则很容易被利用
我有一个 Python 主程序,它导入另一个具有多个功能的模块(称为动作)。主程序应该运行一些东西,得到一个字符串(即goto(114))然后运行 actions.goto(114),其中114是函数goto( x) 在行动中。
我已经尝试了明显的尝试 运行 字符串,但是没有用。我还找到了 globals() 方法,如果 goto(x) 在我的主模块中,它会起作用,我还找到了 getattr 方法,但在这种情况下,我还没有找到我传递函数名称和争论所以我有点迷路了。
#main.py
import actions
def main():
getc = 'goto(114)'
result = actions.getc #this would be actions.goto(114)
print result
#actions.py
def goto(x):
#code
return something
实际程序从另一个程序编写的.txt文件中获取字符串,我只是这样制作示例以便于理解。
您可以使用的一个选项是 action
class 上的 __getattribute__
来获取函数 goto
,然后使用包含的参数调用它。您需要像这样解析它:
import re
import action
getc = 'goto(114)'
func, arg = re.search('(\w+)\((\d+)\)', 'goto(114)').groups()
# f is the function action.goto with the argument 114 supplied as an int
# __getattribute__ allows you to look up a class method by a string name
f = action.__getattribute__(func)
# now you can just call it with the arg converted to int
result = f(int(arg))
正则表达式可能需要改进一下,但它正在查找调用函数的名称以及括在括号中的参数。 __getattribute__
将从 action
和 return 中获取函数对象,它未被调用,因此您可以稍后调用它。
对于多个参数,您可以利用 ast
库:
import re
import ast
# I'm going to use a sample class as a stand-in
# for action
class action:
def goto(*args):
print(args)
getc = 'goto(114, "abc", [1,2,3])'
func, args = re.search('(\w+)\((.*)\)', getc).groups()
# will convert this into python data structures
# safely, and will fail if the argument to literal_eval
# is not a python structure
args = ast.literal_eval('(%s)' % args)
f = getattr(action, func)
f(*args)
# 114, "abc", [1,2,3]
更简单的选择(谨慎行事)是使用 eval
:
cmd = 'action.%s' % getc
result = eval(cmd)
请注意,尽管标准库中有使用它的示例,但在 python 社区中这被认为是不好的做法。这对 un-validated 代码来说是不安全的,如果您不监视源文件
则很容易被利用