[英]How do I pass function definition to python script as string
I want to pass function definition to a python command line script. 我想将函数定义传递给python命令行脚本。 What is the best way to do this?
做这个的最好方式是什么? I am using python 2. Suppose i have a script like this:
我正在使用python 2.假设我有一个这样的脚本:
#myscript.py
x = load_some_data()
my_function = load_function_definition_from_command_line()
print my_function(x)
And i want to call it like this: python myscript.py 'def fun(x): return len(x)'
我想这样称呼:
python myscript.py 'def fun(x): return len(x)'
How do i perform the load_function_definition_from_command_line
part ? 我如何执行
load_function_definition_from_command_line
部分?
I imagine a workaround: 我想象一个解决方法:
But I am sure there must be a better way. 但我相信必须有更好的方法。
You can use eval
to run code defined in a string. 您可以使用
eval
运行字符串中定义的代码。 Like so: 像这样:
import sys
x = load_some_data()
function = eval("".join(sys.argv[1:]))
print(function(x))
With your specific example though you might have to use something like lambda x: len(x)
使用您的具体示例,您可能必须使用
lambda x: len(x)
As @Jan-Spurny rightly points out: "Never, never, never use eval unless you're absolutely sure there is no other way. And even then you should stop and think again." 正如@ Jan-Spurny正确地指出的那样:“永远,永远,永远不要使用eval,除非你绝对确定没有别的办法。即便如此,你也应该停下来思考。”
In my mind the better strategy would be to turn the data loader and executor into a module with a method that takes a function as an argument and runs the desired code. 在我看来,更好的策略是将数据加载器和执行器转换为一个模块,其中一个方法将函数作为参数并运行所需的代码。 The end result something like this:
最终结果是这样的:
import data_loader_and_executor
def function(x):
return len(x)
data_loader_and_executor.run(function)
Use function exec : 使用函数exec :
import sys
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()['fun']
Of course you have to know, how your function will be named, but this can be done by passing to your argument second argument: 当然你必须知道你的函数将如何命名,但这可以通过传递给你的参数第二个参数来完成:
$ python myscript.py 'def fun(x): return len(x)' fun
And then your function will look like: 然后你的功能将如下所示:
import sys
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()[sys.argv[2]]
!!Remember though, that evaluating user input is very dangerous!! !!记住,评估用户输入是非常危险的!
Edit : Since fun
would be the only object defined in locals
, you can just return first element in locals()
: 编辑 :由于
fun
是locals
定义的唯一对象,你可以只返回locals()
第一个元素:
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()[0]
You can use eval or exec to create a function in your current namespace. 您可以使用eval或exec在当前命名空间中创建函数。
exec "somefunc(x): return x * 2"
somefunc(2) # 2
Example within your context 您的上下文中的示例
python load_function.py "def f(x): return x * 2"
//load_function.py
import sys
exec sys.argv[1]
print f(2)
Command line output: 命令行输出:
4
Edit: Obligatory, "It is not wise to execute user input like this." 编辑:强制性,“执行这样的用户输入是不明智的。”
The most obvious source for the correct answer on how to do this is in the timeit
python builtin library. 关于如何做到这一点的正确答案的最明显的来源是
timeit
python内置库。
It is invoked like this: 它被调用如下:
$ python -m timeit '"-".join(str(n) for n in range(100))'
and you can find the source code here, which uses compile
and exec
to invoke the code from the command line 你可以在这里找到源代码,它使用
compile
和exec
从命令行调用代码
https://hg.python.org/cpython/file/2.7/Lib/timeit.py#l143 https://hg.python.org/cpython/file/2.7/Lib/timeit.py#l143
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.