Cython kompiliert ein Python-Projekt

Cython kompiliert ein Python-Projekt

Einführung

cythonizeist ein Befehlszeilentool für den Cython-Compiler, das den Erstellungsprozess von Cython-Erweiterungsmodulen vereinfacht. Cython ist ein Tool zum Schreiben von Python-Erweiterungsmodulen, das die Verwendung der Syntax und Leistung von C in Python ermöglicht und gleichzeitig die Flexibilität und Benutzerfreundlichkeit von Python beibehält.

Konkretcythonize wird verwendet, um Cython-Quelldateien (.pyx) in C-Code zu kompilieren und sie schließlich in gemeinsam genutzte Bibliotheken oder Erweiterungsmodule zur Verwendung durch Python einzubauen. Das Ziel dieses Tools besteht darin, die Leistung zu verbessern und gleichzeitig die Einfachheit und Lesbarkeit der Python-Codierung beizubehalten.

Installieren

  • Python installiert Cython

    pip install cpython
    
  • Linux-Installation: Python-Devel, GCC

    Lecker, installiere Python-Devel

    Lecker, gcc installieren

Kompilierung einzelner Dateien

  • Befehlszeilenkompilierung

    cythonize -i 文件名
    
  • Basierend auf setup.py

     from setuptools import setup
     from Cython.Build import cythonize
    
     setup(
         name = 'test',
         ext_modules = cythonize("test.pyx"),
         zip_safe = False,
     )
    
    python setup.py build_ext --inplace
    

Kompilieren Sie das gesamte Projekt

# -*- coding: utf-8 -*-
"""

执行前提:
     系统安装python-devel 和 gcc
     Python安装cython
 
编译整个当前目录:
     python py-setup.py
编译某个文件夹:
     python py-setup.py BigoModel
 
生成结果:
     目录 build 下
 
生成完成后:
     启动文件还需要py/pyc担当,须将启动的py/pyc拷贝到编译目录并删除so文件
 
"""
 
import sys, os, shutil, time
from distutils.core import setup
from Cython.Build import cythonize
 
starttime = time.time()
currdir = os.path.abspath('.')
if len(sys.argv) >= 2:    
    path_list = sys.argv[1:]
else:
    path_list = ['.']
print("======")
print("build path:", path_list)
print("======")
#parentpath = sys.argv[1] if len(sys.argv)>1 else ""
#if parentpath == '':
#    print("Error:CopyDir is null!")
#    sys.exit(1)

setupfile= os.path.join(os.path.abspath('.'), __file__)
build_dir = "build"
build_tmp_dir = build_dir + "/temp"
 
def getpy(parentpath='', name='', excepts=(), copyOther=False,delC=False, except_fname=()):
    """
    获取py文件的路径
    :param parentpath: 父路径
    :param name: 文件/夹
    :param excepts: 排除文件
    :param copyOther: 是否copy其他文件
    :param delC: 是否删除C文件
    :param except_fname: 排除的文件名
    :return: py文件的迭代器
    """
    fullpath = os.path.join(parentpath, name)
    for fname in os.listdir(fullpath):
        if fname in except_fname:
            continue
        ffile = os.path.join(fullpath, fname)
        #print('{}\n{}\n{}'.format(parentpath, name, fname))
        #print('-----')
        if os.path.isdir(ffile) and fname != build_dir and not fname.startswith('.'):
            if fname == "__pycache__":
                continue
            for f in getpy(os.path.join(parentpath, name), fname, excepts, copyOther, delC, except_fname):
                yield f
        elif os.path.isfile(ffile):
            ext = os.path.splitext(fname)[1]
            if ext == ".c":
                if delC and os.stat(ffile).st_mtime > starttime:
                    os.remove(ffile)
            elif ffile not in excepts and os.path.splitext(fname)[1] not in('.pyc', '.pyx'):
                if os.path.splitext(fname)[1] in('.py', '.pyx') and not fname.startswith('__'):
                    yield os.path.join(parentpath, name, fname)
                if fname == '__init__.py' and copyOther:
                    dstdir = os.path.join(build_dir, parentpath, name)
                    if not os.path.isdir(dstdir): 
                        os.makedirs(dstdir)
                    shutil.copyfile(ffile, os.path.join(dstdir, fname))
            if copyOther:
                if ffile in excepts:
                    continue
                exclude_suffix = ('.pyc', '.pyx', '.py', '.c')
                if os.path.splitext(fname)[1] in exclude_suffix\
                    or fname.startswith('__'):
                    continue
                dstdir = os.path.join(build_dir, parentpath, name)
                if not os.path.isdir(dstdir): 
                    os.makedirs(dstdir)
                shutil.copyfile(ffile, os.path.join(dstdir, fname))
        else:
            print('#pass [%s]...'%(ffile))
            pass


if __name__ == "__main__": 
    
    for parentpath in path_list:
        #获取py列表
        module_list = list(getpy(parentpath=parentpath, excepts=(setupfile), except_fname=("jupyter_config.py")))
        print(module_list)
        try:
            setup(ext_modules = cythonize(module_list, language_level=3),
               script_args=["build_ext", "-b", build_dir, "-t", build_tmp_dir]
               )
        except Exception as e:
             print (e)
        else:
             module_list = list(getpy(parentpath=parentpath, excepts=(setupfile), copyOther=True))
        module_list = list(getpy(parentpath=parentpath, excepts=(setupfile), delC=True))
        if os.path.exists(build_tmp_dir): 
            shutil.rmtree(build_tmp_dir)
        
        print('## setup [{}] over ...'.format(parentpath))
                
    print("complate! time:", time.time()-starttime, 's')

Nachdem die Kompilierung abgeschlossen ist, führen Sie den Anruf durch.

import main

app = main.app
app.run(host='0.0.0.0',port=8037)

Ich denke du magst

Origin blog.csdn.net/qq128252/article/details/134837582
Empfohlen
Rangfolge