从 YAML 文件传递​​ Python 函数

eng*_*019 3 python yaml

我有一个 YAML 脚本,用户可以在其中定义一些参数。他们还可以在 YAML 文件中声明他们想要应用的自定义函数。例如:

processes:
    args1: 10
    args2: 5
    funct: np.sum
Run Code Online (Sandbox Code Playgroud)

该 YAML 将被传递给如下函数:

def custom_func(args1, args2, funct):
    return funct(args1, args2)
Run Code Online (Sandbox Code Playgroud)

对于上面的 YAML 示例,我希望custom_func()执行np.sum(10,5). 如何使 YAML 文件中的数据解析为 Callable?eval()可能可以完成这项工作,但可能存在安全问题。有没有什么正确的方法呢?谢谢!

JL *_*ret 6

您还可以加载给定 Python 点路径的函数。

但是,这仅获取函数并调用它,它不会尝试找出调用签名,这是np.sum([5,10]),而不是np.sum(10,5)

from yaml import safe_load as yload
from importlib import import_module

def load_func(dotpath : str):
    """ load function in module.  function is right-most segment """
    module_, func = dotpath.rsplit(".", maxsplit=1)
    m = import_module(module_)
    return getattr(m, func)
    
yaml = """
processes:
    args1: 10
    args2: 5

    #gotta give real package name, not `np`
    funct: numpy.sum
"""

di = yload(yaml)
pr = di["processes"]
func = load_func(pr["funct"])
array = [pr["args1"], pr["args2"]]

print (f"{func=} {func(array)=}")

Run Code Online (Sandbox Code Playgroud)

输出:

func=<function sum at 0x106645e50> func(array)=15
Run Code Online (Sandbox Code Playgroud)