提问人:doggo 提问时间:5/4/2020 最后编辑:doggo 更新时间:5/4/2020 访问量:176
python 中是否有等效的工具来模仿 C 中预处理器的行为?
Is there an equivalent tool in python to mimic the behaviour of the pre-processor in C?
问:
想要定义许多不同的函数,这些函数在 C 中具有相同的原型并不少见。
int f(int x, int y, char z, char *w);
int g(int x, int y, char z, char *w);
int h(int x, int y, char z, char *w);
int i(int x, int y, char z, char *w);
int j(int x, int y, char z, char *w);
为了在不更改多行代码的情况下为每个函数添加附加参数的可能性,我可以使用预处理器来保持灵活性:
#define FUNCTION(func) int (func)(int x, int y, char z, char *w)
然后用
FUNCTION(f);
FUNCTION(g);
FUNCTION(h);
FUNCTION(i);
FUNCTION(j);
然后,当我去定义函数时,我会使用如下行:
FUNCTION(f)
{
//do something with x,y,z,w
}
FUNCTION(g)
{
//do something else with x,y,z,w
}
有没有办法在python中完成这一点?即是否可以在 Python 中定义许多函数,所有这些函数都采用完全相同的参数,然后通过更改一行来修改它们的参数(例如添加或删除一个参数)?
答:
你不会像在 C 中那样在 Python 中转发声明函数,所以这个问题的前提没有多大意义。最接近的类比是在类型声明中,您确实可以为其别名:
from typing import Callable
FUNCTION = Callable[[int, int, str, str], int]
您还可以让函数本身返回函数,并可能以这种方式消除大量重复,但您的示例不包括函数的主体,因此不会真正映射。
对于您在编辑中描述的情况,您可以不声明参数类型并改用 *args:
def f(*args):
x, y, z, w = args
或者对于类型安全的解决方案(因为很难键入 *args 和 **kwargs),您可以让这些函数采用单个(类型化)元组参数:
FUNCTION_ARGS = Tuple[int, int, str, str]
def f(args: FUNCTION_ARGS):
# next line will throw a mypy error if it doesn't match FUNCTION_ARGS
x, y, z, w = args
评论
标准 Python 没有内置的宏工具,除了 / 之外,不支持静态生成元编程。eval
exec
排除 Python 仅提供动态(运行时)元编程,显然这是一种设计选择;例如,它确实提供了装饰器,可以涵盖一些用例。此外,Python 源代码的读取(解析)是一成不变的,没有办法扩展语法。eval/exec
在运行时创建函数和类的简单方法是将它们的源代码构建为文本字符串,并在其上调用 或。这就是标准库的作用,例如 .eval
exec
namedtuple
此外,Python VM 的几乎所有低级部分都公开了;您可以访问 Python 字节码,例如,您可以以这种方式生成函数,但这是一个非常具有挑战性的操作,因为您需要注意很多细节(例如堆栈效果),而且其中一些内部结构不能保证在 Python 版本之间稳定。从理论上讲,仅使用 Python 可以在 Python 本身中重新实现,但这将是相当困难的,因为您必须自己重写 Python 编译器的相当大一部分(即用 C 编写)。exec
还有人试图使用 Python 提供的内容(或忘记禁止)为 Python 添加宏功能......但是,我没有这方面的经验。
评论
ast
ast
f[_ * _]
def f(_0): return _0 * _0
range(5) | pow(_, 2) | sum
sum(pow(n, 2) for n in range(5)
评论