python - Python 和 C 的单一源文件
问题描述
我正在写一个小模块,它将在 Python 和 C 中都使用。我可以编写一个 Python 版本和一个 C 版本,或者我可以编译 C 版本然后集成到 Python 中。但由于该模块主要是数学计算,在 Python 和 C 中基本相同,我正在考虑编写一个既可以在 Python 中导入又可以作为 C 源代码编译的文件。
这是一个基本技巧:
#if 1 /*
write Python code here
''' */
write C code here
#endif // '''
因此 Python 解释器将忽略 C 部分,而 C 编译器将忽略 Python 部分。
例如,以下内容foo.py
:
#if 1 /*
from math import sin, cos, sqrt
''' */
#include <math.h>
#endif // '''
#if 1 /*
def rotation(axis, angle):
matrix = [0.] * 9
''' */
void rotation(double *axis, double angle, double *matrix) {
double sa, ca, ia, r, x, y, z, xx, yy, zz;
double cayz, caxz, caxy, iayz, iaxy, iaxz, sax, say, saz;
#endif // '''
sa = sin(angle);
ca = cos(angle);
ia = 1. - ca;
r = sqrt(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]);
x = axis[0] / r;
y = axis[1] / r;
z = axis[2] / r;
xx = x * x;
yy = y * y;
zz = z * z;
cayz = ca * (yy + zz);
caxz = ca * (xx + zz);
caxy = ca * (xx + yy);
iayz = ia * y * z;
iaxz = ia * x * z;
iaxy = ia * x * y;
sax = sa * x;
say = sa * y;
saz = sa * z;
matrix[0] = cayz + xx;
matrix[1] = iaxy - saz;
matrix[2] = iaxz + say;
matrix[3] = iaxy + saz;
matrix[4] = caxz + yy;
matrix[5] = iayz - sax;
matrix[6] = iaxz - say;
matrix[7] = iayz + sax;
matrix[8] = caxy + zz;
#if 1 /*
return matrix
''' */
}
#endif // '''
在 Python 中:
from foo import rotation
print(rotation([1., 2., 3.], 4.))
在 C 中:
#include "foo.py"
int main() {
double axis[3] = {1., 2., 3.};
double angle = 4.;
double matrix[9];
rotation(axis, angle, matrix);
printf("[%lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf]",
matrix[0], matrix[1], matrix[2],
matrix[3], matrix[4], matrix[5],
matrix[6], matrix[7], matrix[8]);
return 0;
}
现在我想知道是否可以更进一步,使用一些更好的模式(例如宏)来定义:
- 全局(常量)数组和矩阵
- 简单的控制流、条件和循环
或其他一些改进。
解决方案
这个提议的根本问题是在编译 C 的同时解释 Python。
当您将 C 源代码通过预处理器一次时,这是 C 构建工具链的默认行为,对于 Python,您必须构建一个工具,将 .py 文件通过 C 预处理器,然后通过每次你想运行代码时输出到 Python 解释器。
您的运行时将需要 Python 解释器和您的特殊工具,并且代码将不再可移植到没有这种依赖关系的系统。
这是一个不存在的问题的复杂解决方案。
推荐阅读
- reactjs - 将节点添加到现有节点后如何在antd中重新渲染树?
- excel - VBA & Selenium - 代理并没有真正连接
- swift - 将鼠标悬停在 NSTextView 中的特定单词上时触发事件
- csv - 如何在 Windows 命令提示符本身中查看 CSV 文件?
- python - 改进 python ARIMA 预测
- php - 将文件上传到 laravel 7 时总是返回 null
- sql - Hive Query 不允许 >= 在 where 子句的子查询中
- javascript - 我在我的 node.js 代码中收到此错误“无法读取未定义的属性 'split'”。如何解决这个问题?
- javascript - JavaScript:从数组中查找总和值最高的对象
- disassembly - 只需使用 ptrace 请求进行反汇编