简体   繁体   English

如何将函数定义作为字符串传递给python脚本

[英]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: 我想象一个解决方法:

  1. get the string function definition from command line 从命令行获取字符串函数定义
  2. write it to a file with .py extension in some temp directory 将它写入某个临时目录中扩展名为.py的文件
  3. load the definition from file using solutions from this question: How to import a module given the full path? 使用此问题的解决方案从文件加载定义: 如何在给定完整路径的情况下导入模块?
  4. execute 执行
  5. cleanup 清理

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() : 编辑 :由于funlocals定义的唯一对象,你可以只返回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 你可以在这里找到源代码,它使用compileexec从命令行调用代码

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.

相关问题 如何将URL中的参数字符串传递给GAE中的Python函数? - How do I pass a parameter string in a URL to a Python function in GAE? 如何将可格式化的字符串传递给 python function? - How do I pass a format-able string to a python function? Python:如何通过引用传递字符串? - Python: How do I pass a string by reference? 如何将python函数定义(以及其他任何内容)与RegEx相匹配? - How do I match a python function definition (and nothing else) with RegEx? 我如何覆盖python中嵌入的函数/定义值 - how do i override imbedded function/definition values in python 如何在Python脚本中将用户输入字符串作为参数传递给函数? - How can I pass a user input string to a function as arguments in a python script? 如何将变量(字符串)从 python 传递给 bash 脚本,然后回显它? - How do I pass a variable (string) to a bash script from python and later echo it? 如何在Python中将数组传递给函数? - How do I pass an array to a function in Python? 如何让 Ansible 将变量传递到具有输入 Function 的 Python 脚本? - How do I get Ansible to pass a variable into Python Script that has an Input Function? 如何在Python中将列表的整数项作为字符串参数传递给函数? - How do I pass integer items of a list to a function as string arguments in Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM