我有一个Python主程序,该程序可以导入具有多个功能的另一个模块(称为动作)。主程序应该运行一些东西,获取一个字符串(即goto(114)),然后运行actions.goto(114),其中114是动作中函数goto(x)的参数。
我已经尝试了显而易见的方法,该方法只是尝试运行字符串,但这没有用。我还找到了如果goto(x)在我的主模块中也可以使用的globals()方法,并且我也找到了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文件中获取字符串的,我只是以这种方式制作了示例,以使其易于理解。
答案 0 :(得分:0)
您可以使用的一个选项是__getattribute__
类上的action
,以获取函数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
获取函数对象,并以未调用的方式返回它,因此您以后可以调用它。
对于多个参数,您可以利用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社区中这被认为是不好的做法。对于未经验证的代码,这是不安全的,如果您不监视源文件,很容易被利用