cython,加速python,保护代码(3):扩展文件 .pxd

来源:互联网 发布:mac apowersoft 编辑:程序博客网 时间:2024/06/06 05:25

http://docs.cython.org/src/tutorial/pure.html


.pxd文件相当于c语言中的头文件.h。

In addition to the .pyx source files, Cython uses .pxd files which work like C header files – they contain Cython declarations (and sometimes code sections) which are only meant for inclusion by Cython modules. A pxd file is imported into a pyx module by using the cimport keyword.


Using an augmenting .pxd allows to let the original .py file completely untouched. On the other hand, one needs to maintain both the .pxd and the .py to keep them in sync.

While declarations in a .pyx file must correspond exactly with those of a .pxd file with the same name (and any contradiction results in a compile time error, see pxd files), the untyped definitions in a .py file can be overridden and augmented with static types by the more specific ones present in a .pxd.

If a .pxd file is found with the same name as the .py file being compiled, it will be searched for cdef classes and cdef/cpdef functions and methods. The compiler will then convert the corresponding classes/functions/methods in the .py file to be of the declared type. Thus if one has a file A.py:

def myfunction(x, y=2):    a = x-y    return a + x * ydef _helper(a):    return a + 1class A:    def __init__(self, b=0):        self.a = 3        self.b = b    def foo(self, x):        print x + _helper(1.0)

and adds A.pxd:

cpdef int myfunction(int x, int y=*)cdef double _helper(double a)cdef class A:    cdef public int a,b    cpdef foo(self, double x)

then Cython will compile the A.py as if it had been written as follows:

cpdef int myfunction(int x, int y=2):    a = x-y    return a + x * ycdef double _helper(double a):    return a + 1cdef class A:    cdef public int a,b    def __init__(self, b=0):        self.a = 3        self.b = b    cpdef foo(self, double x):        print x + _helper(1.0)

Notice how in order to provide the Python wrappers to the definitions in the .pxd, that is, to be accessible from Python,

具体规则:

  • Python visible function signatures must be declared as cpdef (with default arguments replaced by a * to avoid repetition):

    cpdef int myfunction(int x, int y=*)
  • C function signatures of internal functions can be declared as cdef:

    cdef double _helper(double a)
  • cdef classes (extension types) are declared as cdef class;

  • cdef class attributes must be declared as cdef public if read/write Python access is needed, cdef readonly for read-only Python access, or plain cdef for internal C level attributes;

  • cdef class methods must be declared as cpdef for Python visible methods or cdef for internal C methods.

In the example above, the type of the local variable a in myfunction() is not fixed and will thus be a Python object. To statically type it, one can use Cython’s@cython.locals decorator (see Magic Attributes, and Magic Attributes within the .pxd).

Normal Python (def) functions cannot be declared in .pxd files. It is therefore currently impossible to override the types of plain Python functions in .pxd files, e.g. to override types of their local variables. In most cases, declaring them as cpdef will work as expected.





0 0
原创粉丝点击