IT狗工作室

第6篇:Cython的面向对象编程--扩展类的实例化

2020-04-22  本文已影响0人  铁甲万能狗

我们前篇谈到了Cython的访问控制,并且谈论了cdef class关键字的底层操作,顺带也谈论了Python类为什么会比Cython类慢的原因。本篇我们将介绍Cython扩展类的初始化

Cython扩展类实例实例化,C的运行时系统在内存中都为其实例持有一个C结构体的内存区域,对于对象的创建和初始化,当Python调用__ init __时,self参数必须是该扩展类型的有效实例,当调用 __ init __时,通常使用来自参数来初始化类实例属性,但在C底层,在调用 __ init __之前,必须为其扩展类型的实例分配内存,并且结构体的字段都必须处于有效状态。

__ cinit __和__dealloc __方法

__ cinit__是负责执行C级别的类实例属性(指针类型)的内存分配和初始化,并且在外部代码的执行结束前,Cython编译器会默认隐含调用扩展类实例的 __ dealloc __方法,这些行为和C++编译器是一致。

使用__ cinit__的注意事项

我们通过一些例子来列举使用 __ cinit 的情况,下面的是一个Cython扩展类Fruit,在C级别的扩展类,若定义了C指针类型的类属性,在 cinit__方法内完成C类型的类实例属性的初始化和内存分配,是其主要的用途

from libc.stdlib cimport malloc,free

cdef class Fruit(object):
    '''Fruit Type'''
    
    cdef readonly str name
    cdef public double qty
    cdef readonly double price
    cdef double *weight
    
    def __cinit__(self,nm,qt,pc):
        print("__cinit__ method executed")
        self.name=nm
        self.qty=qt
        self.price=pc
        self.weight=<double*>malloc(sizeof(double))
        self.weight[0]=23.33
        
        print("weight: ",self.weight[0])
        
    def __init__(self,nm,qt,pc):
        print("__init__ method executed")

    def amount(self):
        return  self.qty*self.price
    
    def __dealloc__(self):
        print("__dealloc__method executed")
        
        if self.weight!=NULL:
            free(self.weight)

调用代码

#!/usr/bin/python3

import pyximport
pyximport.install()

import cy_fruit
if __name__=='__main__':

    b=cy_fruit.Fruit("banana",23.0,33.0)
    b.amount()
    

Cython扩展类在构造时会保证__ cinit__只能被调用一次,并且在__ init__,__ new__或其他Python级别的构造函数(例如,类方法构造函数)之前被调用, Cython将所有初始化参数传递给 __ cinit __,并在./app.py的Python外部代码在结束之前,隐式调用Fruit类实例b. __ dealloc __

Cython扩展类的快速实例化

更新中....

上一篇下一篇

猜你喜欢

热点阅读