如何在 Python 中将函数保存为字符串?

How to save a function as string in Python?

给定以下 Python 函数形式的数学函数:

import math

def f(x):
    a = x - math.log(x)
    b = x + math.log(x)
    return a / x + b / math.log(x)

有什么办法可以把这个函数转换成像

这样的字符串
expr = '(x - math.log(x)) / x + (x + math.log(x)) / math.log(x)'

这样当我想调用函数时,我可以简单地使用它

func = lambda x: eval(expr)
print(func(3))
# 4.364513583657809

请注意,我想在原始函数中保留 ab。实际上,我有更多的中间变量。另外,我知道 sympy 可以完成类似的任务,但我想知道是否可以将函数转换为字符串,因为这样存储效率更高。

有什么建议吗?

您可能正在寻找符号方程求解器!

Sympy 的 lambdify feature 可以为您做到这一点!

>>> fn = sympy.lambdify("x", '(x - log(x)) / x + (x + log(x)) / log(x)')
>>> fn(x=3)
4.364513583657809

注意:这也在内部使用 eval 作为

您的函数在您将其写入文件时已经一个字符串!

如果函数有效Python,你就可以import

from myfile import expr
print(expr(3))  # 4.364513583657809

警告永远不要这样做

如果你出于某种原因想要一些非常邪恶的逻辑,你可以直接用inspect.getsource(f)保存你的函数,然后做这样的事情

>>> fn_body = """def f(x):
...     a = x - math.log(x)
...     b = x + math.log(x)
...     return a / x + b / math.log(x)
... """
>>> eval(f'lambda {fn_body.split("(")[1].split(")")[0]}, _={exec(fn_body)}: {fn_body.split(" ", 1)[-1].split(")")[0]})')(3)
4.364513583657809

它的工作原理是找到调用函数所需的部分,将源评估为参数之一(将其走私到您的命名空间),然后构建一个匿名函数来调用它

进一步注意事项

  • 不可远程维护
  • 极度脆弱
  • 将破坏或与现有的同名函数冲突,具体取决于用途
  • 您仍然需要 import math 或任何其他库
  • 如果没有更多痛苦,将无法使用默认参数
  • 首先调用 eval()(在创建 lambda 之前)将允许您使用 inspect 来获取签名(.signature())并且您可以将它与 re and/or ast 对于更强大的解析器,但是 1-liner 似乎更令人兴奋
  • 设法同时使用 eval() exec() 来额外帮助邪恶