将文件 x 中指定的函数作为命令行参数传递给 python 中的文件 y 的最佳方法

Best way to pass function specified in file x as commandline parameter to file y in python

我正在编写一个包装器或管道来创建一个 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.pymy_func中定义的函数

在 python 中有没有办法做到这一点,如果有,最好的方法是什么?

  1. 将文件名作为参数传递给脚本(和函数名)
  2. 将文件读入字符串,可能提取给定的函数
  3. 使用Pythonexec()执行代码

一个例子:

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的使用有些危险,您应该确保该功能是安全的-如果您正在使用它就没问题!

希望对您有所帮助。

好的,我现在使用来自评论和 的信息自己编写了答案。

    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)

这完全解决了问题,因为我得到了一个可调用函数对象,我可以调用它,传递它,将它用作普通函数。