将文件x中指定的函数作为命令行参数传递给python中的文件y的最佳方法
Posted
技术标签:
【中文标题】将文件x中指定的函数作为命令行参数传递给python中的文件y的最佳方法【英文标题】:Best way to pass function specified in file x as commandline parameter to file y in python 【发布时间】:2020-02-21 18:48:16 【问题描述】:我正在编写一个包装器或管道来创建一个 tfrecords 数据集,我想向该数据集提供一个函数以应用于该数据集。
我想让用户能够注入在另一个 python 文件中定义的函数,该文件在我的脚本中调用以转换数据。
为什么?用户唯一需要做的就是编写将他的数据转换为正确格式的函数,然后由现有代码完成剩下的工作。
我知道我可以让用户在同一个文件中编写函数并调用它,或者有一个导入语句等。
作为一个最小的例子,我想要文件 y.py
def main(argv):
# Parse args etc, let's assume it is there.
dataset = tf.data.TFRecordDataset(args.filename)
dataset = dataset.map(args.function)
# Continue with doing stuff that is independent from actual content
所以我想做的是这样的
python y.py --func x.py my_func
并在dataset.map(...)中使用x.py my_func中定义的函数
有没有办法在 python 中做到这一点,如果有,这是最好的方法吗?
【问题讨论】:
那么你在 x.py 中定义了一个函数 my_func 吗?为什么不from x import my_func
然后调用 my_func(...)
就像您通常使用本地定义的函数一样?或者import x
然后打电话给x.my_func(...)
?
@JustinEzequiel 正如问题中提到的,我知道这个解决方案,但我不想使用它,但能够将函数传递给调用脚本。
那你见过importlib.import_module吗?这是你的用例,我不明白。
“我正在编写一个包装器或管道来创建一个 tfrecords 数据集,我想向该数据集提供一个应用于数据集的函数。”这是我的用例。 “有没有办法在 python 中做到这一点,如果是的话,这是最好的方法吗?”这就是问题。所以你的答案是,没有办法做到这一点,或者说没有任何情况下这是有意义的?
【参考方案1】:
-
将文件名作为参数传递给脚本(和函数名)
将文件读入字符串,可能提取给定函数
使用 Python exec() 执行代码
一个例子:
file = "def fun(*args): \n return args"
func = "fun(1,2,3)"
def execute(func, file):
program = file + "\nresult = " + func
local =
exec(program, local)
return local['result']
r = execute(func, file)
print(r)
类似于here,但是我们必须使用locals()
,因为我们不在全局范围内调用exec
。
注意:exec
的使用有些危险,您应该确保该功能是安全的 - 如果您正在使用它就可以了!
希望这会有所帮助。
【讨论】:
既然exec返回None,它怎么能作为一个函数来返回转换后的元素呢?或者它如何返回指定函数返回的任何内容? 讨论here。肯定有比使用exec
更好的方法!
好的,我可以通过使用另一个包装函数使其工作,这将是一个完全解决问题中指定问题的解决方案。因此,我正在等待更多反馈,但如果没有更好的反馈,如果您稍微编辑它以包含此信息,这可能是一个可接受的答案;)
@hechth 我已经更新了一个例子。我希望这就是你所追求的。【参考方案2】:
好的,我现在使用来自 cmets 和 this answer 的信息自己编写了答案。
import importlib, inspect, sys, os
# path is given path to file, funcion_name is name of function and args are the function arguments
# Create package and module name from path
package = os.path.dirname(path).replace(os.path.sep,'.')
module_name = os.path.basename(path).split('.')[0]
# Import module and get members
module = importlib.import_module(module_name, package)
members = inspect.getmembers(module)
# Find matching function
function = [t[1] for t in members if t[0] == function_name][0]
function(args)
这正好解决了这个问题,因为我得到了一个可调用的函数对象,我可以调用、传递、将其用作普通函数。
【讨论】:
以上是关于将文件x中指定的函数作为命令行参数传递给python中的文件y的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章