当前位置: 首页 > 科技观察

使用C

时间:2023-03-14 15:43:28 科技观察

C模块优化您的Python代码Cython创建的C模块可以加快Python代码的执行速度,这对于使用低效解释语言编写的复杂应用程序非常重要。Cython是Python编程语言的编译器,旨在优化性能并形成Cython编程语言的扩展。Cython作为Python的扩展,也是Python语言的超集,支持调用C函数,在变量和类属性上声明C类型。这使得包装外部C库、将C嵌入现有应用程序或为Python编写类似Python的简单C语言扩展语法变得容易。Cython一般用于创建C模块以加速Python代码的执行。这在使用效率不高的解释型语言编写的复杂应用程序中非常重要。安装Cython您可以在Linux、BSD、Windows或macOS上安装Cython以使用Python:$python-mpipinstall一旦安装了Cython,您就可以使用它。将Python转换为C以使用Cython的一个好方法是从一个简单的“helloworld”开始。这不是展示Cython优点的最佳方式,但它展示了使用Cython时会发生什么。首先,创建一个名为hello.pyx的简单Python脚本(.pyx扩展名并不神奇,技术上它可以是任何东西,但它是Cython的默认扩展名):print("helloworld")接下来,创建一个Python安装脚本。一个类似于Pythonmakefile的setup.py,Cython可以使用它来处理您的Python代码:C代码:$pythonsetup.pybuild_ext--inplace您可以在您的项目目录中看到结果。Cython的cythonize模块将hello.pyx转换为hello.c文件和.so库。这段C代码有2648行,因此它比一行hello.pyx源代码的文本要多得多。.so库也比其源代码大2000倍(即54000字节与20字节相比)。然后,Python需要运行单个Python脚本,因此有很多代码来支持这个单行hello.pyx文件。要使用Python的“helloworld”脚本的C代码版本,请打开Python提示符并导入您创建的新hello模块:>>>importhellohelloworld将C代码集成到Python中是对计算能力的一个很好的测试一个常见的测试是计算质数。质数是大于1的正数,只有被1或它本身除时才产生正整数。虽然理论很简单,但随着数字变大,计算需求也会增加。在纯Python中,素数的计算可以用不到10行代码完成。importsysnumber=int(sys.argv[1])ifnotnumber<=1:foriinrange(2,number):if(number%i)==0:print("Notprime")breakelse:print("Integermustbegreaterthan1")此脚本成功时不会提示。如果数字不是质数,它会返回一条消息:$./prime.py3$./prime.py4Notprime。将这些转换为Cython需要一些工作,部分是为了使代码适合用作库,部分是为了提高性能。脚本和库许多用户将Python作为一种脚本语言来学习:您告诉Python您希望它执行的步骤,它就会执行。随着您对Python(以及一般的开源编程)的了解越来越多,您会了解到库中存在许多其他应用程序可以利用的强大代码。您的代码越不具体,程序员(包括您)就越有可能将其重用于其他应用程序。解耦计算和工作流可能需要更多的工作,但最终通常是值得的。在这个简单的素数计算示例中,要将其转换为Cython,首先是一个设置脚本:fromsetuptoolsimportsetupfromCython.Buildimportcythonizesetup(ext_modules=cythonize("prime.py")).pybuild_ext--inplace到目前为止一切似乎都工作正常,但是当您尝试导入和使用新模块时,您会看到一个错误:>>>importprimeTraceback(mostrecentcalllast):File"",line1,inFile"prime.py",line2,ininitprimenumber=sys.argv[1]IndexError:listindexoutofrange这个问题是Python脚本期望从终端运行其中参数(在本例中为测试素数的整数)相同。您需要修改脚本以使其可用作库。编写一个不使用系统参数但接受来自其他代码的参数的库。对于用户输入,不要使用sys.argv,而是将您的代码包装在一个函数中,该函数接受一个名为number(或num,或您喜欢的任何变量名称)的参数:defcalculate(number):ifnotnumber<=1:foriinrange(2,number):if(number%i)==0:print("Notprime")breakelse:print("Integermustbegreaterthan1")这确实让你的脚本有些难以测试,因为当您在Python中运行代码时,永远不会执行计算函数。然而,Python程序员已经为这个问题设计了一个通用的、有些直观的解决方案。当Python解释器执行Python脚本时,有一个名为__name__的特殊变量被设置为__main__,但当它作为模块导入时,__name__被设置为模块的名称。使用它,您可以编写一个既是Python模块又是有效Python脚本的库:importsysdefcalculate(number):ifnotnumber<=1:foriinrange(2,number):if(number%i)==0:print("Notprime")breakelse:print("Integermustbegreaterthan1")if__name__=="__main__":number=sys.argv[1]calculate(int(number))现在你可以使用一个命令运行代码:$python./prime.py4Notaprime你可以将它转换为Cython作为一个模块使用:>>>importprime>>>prime.calculate(4)NotprimeCPython使用Cython它用于将纯Python代码转换为C代码。这篇文章描述了如何做到这一点,但是,Cython还具有可帮助您在转换前优化代码、分析代码以查找Cython何时与C交互等的功能。如果你正在使用Python,但你想用C代码改进你的代码,或者进一步了解该库如何提供比脚本更好的扩展性,或者你只是对Python和C如何协同工作感到好奇,那么请开始使用CythonBar。