当前位置: 首页 > news >正文

Python中使用C扩展详解

文章目录

      • 1. Python/C API
      • 示例
      • 2. Cython
      • 示例
      • 3. ctypes
      • 关于C扩展的进一步讨论
        • 安全性和兼容性
        • 性能优化策略
        • 调试C扩展
        • 发布和分发C扩展
      • 应用实例:加速矩阵乘法运算
        • 1. 准备C扩展代码
        • 2. 编译C扩展
        • 3. 在Python中使用C扩展

在Python中,使用C扩展是一种提高程序性能、访问底层系统资源或复用现有C代码的方法。Python提供了几个库和工具来帮助开发者编写、编译和加载C扩展模块,最常用的有 Python/C APICythonctypes

1. Python/C API

Python/C API允许你直接用C语言编写Python模块。这意味着你可以创建新的数据类型、定义函数,并直接与Python解释器交互。使用API的一般步骤包括:

  • 编写C代码实现功能。
  • 使用API定义Python类型的对象和方法。
  • 编译C代码为共享库(.so文件)。
  • 在Python中通过import语句加载这个库。

示例

一个简单的C扩展模块示例,该模块提供一个函数计算两个整数的和:

// example.c
#include <Python.h>static PyObject* example_add(PyObject* self, PyObject* args) {int a, b;if (!PyArg_ParseTuple(args, "ii", &a, &b)) {return NULL;}return Py_BuildValue("i", a + b);
}static PyMethodDef ExampleMethods[] = {{"add", (PyCFunction)example_add, METH_VARARGS, "Add two numbers"},{NULL, NULL, 0, NULL}
};static struct PyModuleDef examplemodule = {PyModuleDef_HEAD_INIT,"example",   /* name of module */NULL,       /* module documentation, may be NULL */-1,         /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ExampleMethods
};PyMODINIT_FUNC PyInit_example(void) {return PyModule_Create(&examplemodule);
}

编译此代码需要使用Python的开发头文件和库,通常命令如下(假设已安装Python开发包):

gcc -shared -o example.so -I/usr/include/python3.x example.c -lpython3.x

然后在Python中导入这个模块:

import example
print(example.add(1, 2))

2. Cython

Cython是一个更高级的工具,它允许你用类似Python的语法编写代码,然后将其编译成C扩展。Cython添加了静态类型声明,从而能够更高效地调用C库和执行操作。使用Cython,通常涉及以下步骤:

  • 安装Cython。
  • 编写.pyx文件,其中可以混合Python和C类型的注解。
  • 使用Cython编译器生成C代码。
  • 编译生成的C代码到共享库。
  • 在Python中导入这个库。

示例

Cython版本的上述示例:

# example.pyx
def add(int a, int b):return a + b

使用Cython编译并使用这个模块,首先安装Cython(如果尚未安装):

pip install cython

然后编译example.pyx文件:

cythonize -3 -i example.pyx

这将生成一个可以直接在Python中导入的共享库文件。之后在Python中使用:

import example
print(example.add(1, 2))

3. ctypes

ctypes是Python标准库的一部分,它提供了一个更灵活但可能更复杂的途径来调用C库中的函数,而不需要预先编译C代码。你直接在Python中定义C数据类型和函数原型,然后加载动态链接库。

选择哪种方式取决于你的具体需求:如果追求极致性能且不介意更复杂的开发流程,直接使用Python/C APICython可能是最佳选择;如果你只是想简单地调用现有的C库函数,ctypes可能更合适。每种方法都有其优势和适用场景,关键在于权衡开发效率、维护成本和性能需求。

关于C扩展的进一步讨论

安全性和兼容性
  • 安全性:直接使用C扩展时,需要格外小心内存管理和其他潜在的错误,因为C语言不会自动处理这些错误,而Python则设计得更为健壮。使用Cython可以在一定程度上减少这类问题,因为它提供了更多的错误检查。
  • 兼容性:C扩展通常需要针对特定的Python版本编译。这意味着如果你的扩展需要在不同Python版本上运行,可能需要为每个版本分别编译。Cython和Python/C API都提供了宏和条件编译功能来帮助处理兼容性问题。
性能优化策略
  • 减少Python/C切换开销:在编写C扩展时,尽量减少从Python环境到C环境的转换次数。例如,在循环中避免频繁调用Python API。
  • 使用缓冲区协议:对于大量数据处理,利用Python的缓冲区协议(buffer protocol)可以更高效地处理数组和缓冲区数据,避免复制。
  • 多线程和异步:虽然C扩展可以直接使用多线程,但需要注意全局解释器锁(GIL)。对于CPU密集型任务,考虑使用子进程或者结合Python的异步IO功能。
调试C扩展

调试C扩展比调试纯Python代码要复杂一些,但也有相应的工具可用:

  • gdb:GNU调试器,可以用来调试C代码。当你的扩展崩溃或行为异常时,gdb可以帮助定位问题。
  • Cython调试:如果使用Cython,可以在编译时开启调试信息,然后使用gdb或IDE的调试功能。
  • Python的faulthandler模块:可以在Python程序崩溃时输出堆栈跟踪,帮助识别问题所在。
发布和分发C扩展
  • 预编译二进制包:为了便于用户安装,可以为常见的操作系统和Python版本预编译二进制包。
  • 使用CMake或Setuptools:这些工具可以帮助自动化编译过程,使得安装过程对用户更加友好。特别是SetuptoolsExtension类可以用来指定C扩展的编译选项,并自动构建。

C扩展是提升Python应用性能的有效手段,尤其是在处理高性能计算、密集运算或硬件交互等场景。正确使用这些技术,结合良好的编程实践和调试技巧,可以极大地增强Python应用的能力。不过,由于其增加了开发和维护的复杂度,因此在决定是否采用C扩展前,应当仔细评估性能提升与额外工作量之间的平衡。

应用实例:加速矩阵乘法运算

假设我们有一个应用场景,需要频繁进行大规模矩阵乘法运算,而Python原生的矩阵乘法可能无法满足性能要求。这时,通过编写C扩展来加速这一过程是一个不错的选择。这里以使用Python/C API为例,展示如何实现这一优化。

1. 准备C扩展代码

首先,我们编写C代码来实现矩阵乘法。这个C函数将接收两个二维数组(矩阵),计算它们的乘积,并返回结果矩阵。

// matrix_multiply.c
#include <Python.h>void matmul(int n, double* A, double* B, double* C) {for(int i = 0; i < n; ++i) {for(int j = 0; j < n; ++j) {double sum = 0;for(int k = 0; k < n; ++k) {sum += A[i*n+k] * B[k*n+j];}C[i*n+j] = sum;}}
}static PyObject* py_matrix_multiply(PyObject* self, PyObject* args) {int n;PyObject* py_A, *py_B;double* A, *B, *C;// 解析输入参数if (!PyArg_ParseTuple(args, "O!O!i", &PyArray_Type, &py_A, &PyArray_Type, &py_B, &n)) {return NULL;}// 确保输入是二维数组且元素类型为doubleif (PyArray_NDIM(py_A) != 2 || PyArray_NDIM(py_B) != 2 ||PyArray_TYPE((PyObject*)py_A) != NPY_DOUBLE ||PyArray_TYPE((PyObject*)py_B) != NPY_DOUBLE) {PyErr_SetString(PyExc_TypeError, "Input arrays must be 2D and of type double.");return NULL;}// 获取数据指针A = (double*)PyArray_DATA(py_A);B = (double*)PyArray_DATA(py_B);C = (double*)malloc(n*n*sizeof(double));// 执行矩阵乘法matmul(n, A, B, C);// 创建并返回结果numpy数组PyObject* result = PyArray_SimpleNewFromData(2, &n, NPY_DOUBLE, (void*)C);Py_INCREF(result); // 增加引用计数,防止数据被提前释放return result;
}static PyMethodDef MatrixMethods[] = {{"matrix_multiply", py_matrix_multiply, METH_VARARGS, "Multiply two matrices."},{NULL, NULL, 0, NULL}
};// 模块初始化
static struct PyModuleDef matrix_module = {PyModuleDef_HEAD_INIT,"matrix_extension",NULL,-1,MatrixMethods
};PyMODINIT_FUNC PyInit_matrix_extension(void) {import_array(); // 初始化numpy C APIreturn PyModule_Create(&matrix_module);
}
2. 编译C扩展

确保已经安装了NumPy以及Python的开发包,然后使用如下命令编译C扩展:

gcc -shared -o matrix_extension.so -I/usr/include/python3.x -lpython3.x matrix_multiply.c -lpython3.x -lm

请根据你的Python版本和路径调整上述命令。

3. 在Python中使用C扩展

接下来,在Python脚本中导入并使用这个C扩展来加速矩阵乘法运算。

import numpy as np
import matrix_extension# 创建两个随机矩阵
n = 1000
A = np.random.rand(n, n)
B = np.random.rand(n, n)# 使用C扩展进行矩阵乘法
C = matrix_extension.matrix_multiply(A, B, n)print("Resulting matrix shape:", C.shape)

通过这种方式,我们利用C语言的直接内存访问和控制能力,绕过了Python解释器的层次,实现了高效的矩阵乘法运算,显著提高了执行速度。

😍😍 大量H5小游戏、微信小游戏、抖音小游戏源码😍😍
😍😍试玩地址: https://www.bojiogame.sg😍😍
😍看上哪一款,需要源码的csdn私信我😍

————————————————

​最后我们放松一下眼睛
在这里插入图片描述

相关文章:

Python中使用C扩展详解

文章目录 1. Python/C API示例2. Cython示例3. ctypes关于C扩展的进一步讨论安全性和兼容性性能优化策略调试C扩展发布和分发C扩展 应用实例&#xff1a;加速矩阵乘法运算1. 准备C扩展代码2. 编译C扩展3. 在Python中使用C扩展 在Python中&#xff0c;使用C扩展是一种提高程序性…...

llama使用tutorial微调(windows版本)

Llama3-Tutorial/docs/assistant.md at main SmartFlowAI/Llama3-Tutorial GitHub 有一些命令需要修改 前期的安装还是要按照教程搞的 streamlit run ~/Llama3-Tutorial/tools/internstudio_web_demo.py \ ~/model/Meta-Llama-3-8B-Instruct 改为了 streamlit run .\Ll…...

MyBatis操作数据库(动态SQL)

1 动态SQL 动态SQL是MyBatis的特征之一&#xff0c;能够完成不同条件下不同的SQL拼接 1.1 <if>标签 在注册用户的时候&#xff0c;可能会有这样一个问题&#xff0c;由于注册分为两种字段&#xff1a;必填字段和非必填字段&#xff0c;如果在添加用户的时候有不确定的…...

python发票真伪查验开发文档、票据OCR、数电票查验

想象一下&#xff0c;只需一行行简洁的代码&#xff0c;复杂繁琐的发票审核工作瞬间变得井然有序。翔云发票查验开发文档详尽易懂&#xff0c;即便是Python新手也能迅速上手&#xff0c;搭建起自己的发票真伪查验系统。无论是纸质发票的扫描图像&#xff0c;还是电子发票的数据…...

Unity构建详解(12)——自动构建

【前言】 自动构建是指整个构建流程不需要人工操作&#xff0c;只需要输入启动构建指令即可获取构建结果。实现这样的自动构建需要满足以下条件&#xff1a; 支持命令行参数启动 我们不可能每次构建时都打开Unity去手动点击构建&#xff0c;必须支持通过命令行启动Unity自动执…...

中文编程降低了中文环境下编程入门的门槛

近年来&#xff0c;随着编程技术的普及和中文编程环境的日益成熟&#xff0c;越来越多的开发者开始使用中文进行编程。中文编程不仅提高了代码的可读性和理解性&#xff0c;而且在一定程度上降低了中文环境下编程的入门门槛。本文将详细探讨中文编程的优势&#xff0c;以及它如…...

通过内网穿透免费部署我们的springboot+vue项目 实现跟服务器一样的效果

前文讲到通过内网穿透能够实现远程访问个人电脑的静态资源。本文将讲解通过内网穿透实现远程访问本地的项目&#xff0c;实现跟部署到服务器一样的效果&#xff1a;前文链接&#xff1a;通过内网穿透实现远程访问个人电脑资源详细过程&#xff08;免费&#xff09;&#xff08;…...

SMB攻击利用之-mimikatz上传/下载流量数据包逆向分析

SMB协议作为windows环境下最为常见的一种协议,在历史上出现过无数的通过SMB协议进行网络攻击利用的案例,包括针对SMB协议本身以及通过SMB协议实施网络攻击。 本文将介绍一种通过SMB协议的常见利用方式,即向远程主机传输mimikatz,作为我的专栏《SMB攻击流量数据包分析》中的…...

Mysql常见数据类型探索

Mysql常见数据类型探索 数值类型 MySQL 支持所有标准 SQL 数值数据类型。 这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL 和 NUMERIC)&#xff0c;以及近似数值数据类型(FLOAT、REAL 和 DOUBLE PRECISION)。 关键字INT是INTEGER的同义词&#xff0c;关键字DEC是…...

2024 年第四届长三角高校数学建模竞赛赛题B题超详细解题思路+问题一二代码分享

2024年第四届长三角数学建模竞赛B题详细解题思路 赛道B&#xff1a;人工智能范式的物理化学家 长三角分享资料&#xff08;问题一代码论文思路&#xff09;链接&#xff08;18点更新&#xff09;&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1lteKvIWNZ4v-Gd7oOcg…...

干货速学!1+X电子商务数据分析:电子商务数据分析的流程

电商数据采集API接口 生活中的数据分析 日常工作和生活中处处都有数据分析的存在&#xff0c;比如消费者在购买不同商品前&#xff0c;经常会对儿“性价比”进行简单分析&#xff0c;价格表现为固定的货币数字。性能则具体体现在商品质量、客户收务等客观因素和客户对该商品的需…...

618好物推荐大赏:2024年必囤好物一网打尽,购物攻略助你抢购无忧!

在618购物狂欢节来临之际&#xff0c;我为大家精心挑选了一系列好物&#xff0c;它们不仅品质卓越&#xff0c;更能在日常生活中为我们带来无限便利与乐趣。这里的每一款产品都经过我严格筛选&#xff0c;只为给你最优质的购物体验。让我们一起在这个618&#xff0c;发现生活中…...

【MySQL】基础操作(DDL,DML,DCL,DQL)

安装教程自行搜索&#xff0c;网上有很多 用户名设置为 root密码设置为 123456可以不这样设置&#xff0c;但要记好用户名密码&#xff0c;相关的代码也要自行更改 打开命令提示符程序(winR打开输入cmd回车) 输入&#xff1a;mysql -uroot -p 回车输入密码即可进入命令行环境…...

工厂自动化升级改造(3)-Modbus与MQTT的转换

什么是MQTT,Modbus,见下面文章 工厂自动化升级改造参考(01)--设备通信协议详解及选型-CSDN博客文章浏览阅读608次,点赞9次,收藏6次。>>特点:基于标准的以太网技术,使用TCP/IP协议栈,支持高速数据传输和局域网内的设备通信。>>>特点:跨平台的通信协议,…...

InnoDB 事务处理机制

文章目录 前言1. 事务处理挑战1.1 事务机制处理的问题1.2 并发事务带来的问题 2. InnodDB 和 ACID 模型2.1 Innodb Buffer Pool2.2 Redo log2.3 Undo log2.4 应用案例 3. 隔离级别和锁机制3.1 事务隔离级别3.1.1 READ UNCOMMITTED3.1.2 READ COMMITTED3.1.3 REPEATABLE READ3.1…...

Thymeleaf

替代jsp 功能&#xff1a;服务器渲染&#xff08;就是将服务器的数据展示在网页上&#xff09; 1、MVC概念 model 模型 javaBean(User/Book/Order...) View视图 html 服务器的动态数据 Controller控制器 Servlet MVC是在表述层开发运用的一种设计理念。主张把封装数据…...

网络学习(一)|深入了解API网关:定义、功能和关键术语

文章目录 定义主要功能关键术语 定义 API 网关&#xff08;API Gateway&#xff09;是一个核心的服务架构组件&#xff0c;用于管理、路由和保护对后端服务的访问。它充当了系统内外的接口&#xff0c;负责接收来自客户端的请求&#xff0c;并将其路由到相应的后端服务&#x…...

基于yolov8+flask搭建一个web版本的网页模型预测系统

测试环境&#xff1a; anaconda3python3.8 torch1.9.0cu111 ultralytics8.2.2 首先我们将训练好的权重放在weights目录下面 并将名字改成yolov8n.pt&#xff0c;如果不想改可以在代码app.py都把路径改过来即可。然后我们打开 python app.py之后看到 我们点击选择文件支持图…...

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第8章 安装编译所需要的依赖包

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…...

牛客热题:合并二叉树

牛客热题&#xff1a;二叉树与双向链表> &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

HTTPS证书一年多少钱?

HTTPS证书作为保障网站数据传输安全的重要工具&#xff0c;成为众多网站运营者的必备选择。然而&#xff0c;面对市场上种类繁多的HTTPS证书&#xff0c;其一年费用究竟是多少&#xff0c;又受哪些因素影响呢&#xff1f; 首先&#xff0c;HTTPS证书通常在PinTrust这样的专业平…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

Python第七周作业

Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt&#xff0c;并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径&#xff0c;并创建logs目录&#xff08;若不存在&#xff09; 3.递归遍历目录data&#xff0c;输出所有.csv文件的路径…...