IT狗工作室

第6篇:Cython的面向对象编程(前篇)

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

在Python中,一切都是对象。 具体来说是什么意思? 在最基本的层面上,一个对象具有三样东西

Python类型系统

我们知道Python的面向对象编程中,允许用户自定义的数据类型,在实例化Python的类对象时,该实例的属性值会保存到其内部dict中,即__ dict __属性,具有原生Python语义的类,其对象实例化前由Python解析器执行并经历如下过程(有些Python读物将这个过程步骤2到步骤4叫动态分派(Dynamic Dispatch),这里仅给出总结性的描述)

(首次加载序列化mashling格式的字节码)→从字节码缓存文件中解析实例属性的类型动态检查确定实例属性类型(类属性的尺寸)为其在实例化分配堆内存空间

不同类型的组合关系:

要直接在C/C++中实现Python的扩展类型需要开发者熟悉Python C底层接口,因此并不适合没有C/C++经验的开发者,然而Cython已经高度集成几乎所有C/C++的主流特性。能够以类似Python的语法快速定义出C/C++级别的Python扩展类型。

Cython中的扩展类

下面是一个简单的水果类,每种水果都有名称,数量,价格,Fruit类在纯Python的解析级别上定义(默认在.py文件中),当然也可以由Cython编译为C扩展

class Fruit(object):
    '''Fruit Type'''
    def __init__(self,nm,qt,pc):
          self.name=nm
          self.qty=qt
          self.price=pc

    def amount(self):
          return  self.qty*self.price

纯Python代码定义中,我们Frui对象实例化的时间开销是265ns

Cython编译后的Fruit2对象(类定义是一样,类名称不一样),时间开销是217ns

当我们使用cython将Fruit类编译为C时,生成的类只是Python在C级别的用户自定义类型,而不是扩展类型。 当Cython将其编译为C时,它仍然可以使用所有操作的动态分派的通用Python对象来实现。 所生成的代码大量使用Python底层C应用接口,并且与使用纯Python代码定义此类时的Python解释器进行相同的调用。

要将上面的Python类转化为C级别的扩展类,只需对Fruit类做以下代码修改

%%cython -a

cdef class Fruit(object):
    '''Fruit Type'''
    
   #类属性静态
    cdef str name
    cdef double qty
    cdef double price
    
    def __init__(self,nm,qt,pc):
          self.name=nm
          self.qty=qt
          self.price=pc

    def amount(self):
          return  self.qty*self.price


通过对Cython版本的Fruit类的类属性声明语句进行类型静态化后,我们实例化该实例的时间开销非常棒,最好的成绩是85.5ns


Cython编译的扩展类型比纯Python定义的用户定义类型快3倍多,比Cython编译的用户定义类型快2倍


目前这个Cython版本的Fruit类设计还不是最优的版本,我们下篇继续探讨有关Cython面向对象编程中的更多内容。

更新中....

上一篇下一篇

猜你喜欢

热点阅读