I want to pass function definition to a python command line script. What is the best way to do this? I am using python 2. Suppose i have a script like this:
我想将函数定义传递给python命令行脚本。做这个的最好方式是什么?我正在使用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:
我想象一个解决方法:
- get the string function definition from command line
- write it to a file with .py extension in some temp directory
- load the definition from file using solutions from this question: How to import a module given the full path?
- execute
- cleanup
从命令行获取字符串函数定义
将它写入某个临时目录中扩展名为.py的文件
使用此问题的解决方案从文件加载定义:如何在给定完整路径的情况下导入模块?
But I am sure there must be a better way.
但我相信必须有更好的方法。
4 个解决方案
#1
2
You can use eval
to run code defined in a string. Like so:
您可以使用eval运行字符串中定义的代码。像这样:
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)
#2
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"
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
命令行输出:4
Edit: Obligatory, "It is not wise to execute user input like this."
编辑:强制性,“执行这样的用户输入是不明智的。”
#3
0
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()中的第一个元素:
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()[0]
#4
0
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从命令行调用代码
#1
2
You can use eval
to run code defined in a string. Like so:
您可以使用eval运行字符串中定义的代码。像这样:
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)
#2
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"
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
命令行输出:4
Edit: Obligatory, "It is not wise to execute user input like this."
编辑:强制性,“执行这样的用户输入是不明智的。”
#3
0
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()中的第一个元素:
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()[0]
#4
0
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从命令行调用代码