我想将函数定义传递给python命令行脚本。做这个的最好方式是什么?我正在使用python 2.假设我有一个这样的脚本:
if (body.hasClass('page-sidebar-fixed')) {
$('.page-sidebar').on('mouseenter', function () {
if (body.hasClass('page-sidebar-closed')) {
$(this).find('.page-sidebar-menu').removeClass('page-sidebar-menu-closed');
}
}).on('mouseleave', function () {
if (body.hasClass('page-sidebar-closed')) {
$(this).find('.page-sidebar-menu').addClass('page-sidebar-menu-closed');
}
});
}
我想这样称呼:#myscript.py
x = load_some_data()
my_function = load_function_definition_from_command_line()
print my_function(x)
我如何执行python myscript.py 'def fun(x): return len(x)'
部分?
我想象一个解决方法:
但我相信一定有更好的方法。
答案 0 :(得分:2)
您可以使用eval
来运行字符串中定义的代码。像这样:
import sys
x = load_some_data()
function = eval("".join(sys.argv[1:]))
print(function(x))
使用您的具体示例,您可能需要使用lambda x: len(x)
正如@ Jan-Spurny正确地指出的那样:"永远不会,永远不会使用eval,除非你绝对确定没有别的办法。即便如此,你应该停下来思考一下。"
在我看来,更好的策略是将数据加载器和执行器转换为一个模块,其中一个方法将函数作为参数并运行所需的代码。最终结果如下:
import data_loader_and_executor
def function(x):
return len(x)
data_loader_and_executor.run(function)
答案 1 :(得分:0)
使用函数exec:
import sys
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()['fun']
当然你必须知道你的函数将如何命名,但这可以通过传递给你的参数第二个参数来完成:
$ python myscript.py 'def fun(x): return len(x)' fun
然后你的功能将如下:
import sys
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()[sys.argv[2]]
!!请记住,评估用户输入非常危险!!
修改:由于fun
是locals
中定义的唯一对象,因此您只需返回locals()
中的第一个元素:
def load_function_definition_from_command_line():
exec(sys.argv[1])
return locals()[0]
答案 2 :(得分:0)
您可以使用eval或exec在当前命名空间中创建一个函数。
exec "somefunc(x): return x * 2"
somefunc(2) # 2
您的上下文中的示例
python load_function.py "def f(x): return x * 2"
//load_function.py
import sys
exec sys.argv[1]
print f(2)
命令行输出:
4
编辑:强制性,"执行此类用户输入并不明智。"
答案 3 :(得分:0)
关于如何执行此操作的正确答案的最明显来源是timeit
python builtin库。
它是这样调用的:
$ python -m timeit '"-".join(str(n) for n in range(100))'
你可以在这里找到源代码,它使用compile
和exec
从命令行调用代码