python附加篇cpython用法
心得:剛換工作后,連續忙了2個多月,在這兩個多月里,學到的東西也是比較多的,不論從算法上,源碼調試上,還是代碼規范性上都有一定的提升,接下來會將這段時間接觸到內容逐一記錄下來。先從cpython開始吧,cpython用作代碼保護或者能夠提升代碼運行的效率。
Cpython官網:https://cython.readthedocs.io/en/latest/index.html
中文版:https://cython.apachecn.org/#/docs/29?id=%e5%9f%ba%e6%9c%ac-setuppy
一、Cpython簡介
CPython是特指C語言實現的Python,就是原汁原味的Python。主要目的做python的加速,當然在編譯后,相應的對代碼進行了保護
二、快速開始,配置文件以及編譯
創建pyx文件:
hello.pyx
import timet0 = time.time() for i in range(100000):pass print("time is {}".format(time.time()-t0))setup.py
from setuptools import setup from Cython.Build import cythonizesetup(ext_modules=cythonize("hello.pyx") )命令行輸入python setup.py build_ext --inplace對hello.pyx文件進行編譯
將會生成hello.的so動態庫,我們調用此so動態庫即可。
test.py
cpython 輸出
time is 0.002833843231201172
我們用python同樣輸出
time is 0.005338907241821289
速度提高了一半左右,要是將大量的計算方入編譯,速度會有較高的提升
三、cpython中編碼注意事項
Python類型list,dict,tuple,等等可被用于靜態類型
變量類型定義,在pyx文件中定義好了才可以調用
cdef list foo = [] cdef dict fol = {} cdef (double, int) bar在函數中,如果未為參數或返回值指定類型,則假定該類型為Python對象。所以最好在入參和返回值的時候定義變量類型
hello.py 如果變量輸出類型未定義則會輸出None
cdef list l=[1,2,3]def lis(int x,int y):cdef dict c ={}a = x + yl.append(a)c["lis"] = lreturn c輸出:
{'lis': [1, 2, 3, 3]}cpython中比如定義了列表,但經過編譯后,沒辦法正常調用此列表,正確的方式是用函數去返回,用函數將列表包裝再返回。
也可以使用聲明類cdef,使它們成為Extension Types,它們的行為非常接近python類,但是速度更快,因為它們使用struct 內部存儲屬性。
from __future__ import print_functioncdef class Shrubbery:cdef list width, heightdef __init__(self, w, h):self.width = wself.height = hdef describe(self):print("This shrubbery is", self.width,"by", self.height, "cubits.")編譯后test.py
import newres = new.Shrubbery([1,2],[]) res.describe()##輸出 This shrubbery is [1, 2] by [] cubits.注意:將類編譯到cpython中后,從外面調用編譯過的類屬性是拿不到的,如果想拿對應的類屬性,可以編寫對應的方法來獲取屬性。
cdef class Shrubbery:cdef list width, heightdef __init__(self, w, h):self.width = wself.height = hprint(self.width,"width")print("my friends: ",my_friends())def describe(self):print("This shrubbery is", self.width,"by", self.height, "cubits.")def get_width(self):return self.width shr = hello.Shrubbery([1,2],[3,4]) shr.describe() print("width",shr.get_width())四、編譯
1. 基本的setup.py
如果只有一個Cython文件要轉換為已編譯的擴展名,則使用filename example.pyx表示關聯setup.py 如下:
from setuptools import setup from Cython.Build import cythonizesetup(ext_modules = cythonize("example.pyx") )編譯:$ python setup.py build_ext --inplace
2. 包中的多個Cython文件
若要自動編譯多個Cython文件而不顯式列出所有文件,可以使用全局模式:
setup(ext_modules = cythonize("package/*.pyx") )Extension如果通過它們,也可以在對象中使用全局模式cythonize():
extensions = [Extension("*", ["*.pyx"])]setup(ext_modules = cythonize(extensions) )3. 多個包時,setup文件編寫
參考地址
from setuptools import Extension, setup from Cython.Build import cythonizesetup(ext_modules=cythonize("hello.pyx") )# include_dirs,libraries和library_dirs,它們指定鏈接到外部庫時在哪里可以找到.h和庫文件。 # module_list 可以是多個Extension也就是多個pyx文件 ext_modules = cythonize(module_list=[Extension(name="chello",sources=["test.pyx"],libraries=["hello"],include_dirs=['c2/include'],library_dirs=['c2/lib']), ])# ext_modules 要構建的 Python 擴展的列表 # packages distutils將操作的Python軟件包列表, 按包分發,其他的還是元數據,其中name最好是一定要到,如果安裝的話生成的文件會是指定name的名字 setup(name='chello',version="1.1.0",author="作者",ext_modules=ext_modules,description='Python Distribution Utilities',author_email='',url='',packages=['distutils', 'distutils.command'])總結
以上是生活随笔為你收集整理的python附加篇cpython用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【信号处理】基于小波变换的时间重分配多重
- 下一篇: websocket python爬虫_p