03 Cython 数据类型和语法

Dynamic Type(动态类型)和Static Type(静态类型)

Cpython中的static和const

静态类型数据声明

声明多个静态类型变量

Cython指针用法


Dynamic Type(动态类型)和Static Type(静态类型)

Cpython中的static和const

C语言中的关键字static 是用于声明生命周期贯穿整个程序的变量,但并不是Cython中的关键字。

Cython中也没有const关键字,可以将类的成员变量前加一个readonly。

C++、Java和C#都是静态语言,它们最大的特点就是变量在使用之前都必须进行类型声明。而Python、JS则是一种动态类型语言,所谓动态,通俗点说就是变量的类型是由最后赋予它的值决定的。
从运行效率来说静态类型是要优于动态类型的,因为在编译的时候就能确定每一个变量的类型,这样编译器就能对编译的结果做一些优化。而动态类型一般都是解释执行的,变量的类型需要在解释运行的时候才能确定,难免会损失一点性能。
对于如下的c代码:

int a = 1;
int b = 2;
int c = a + b;

假设对于+运算符有多种的实现版本(例如有整数版本、浮点数版本、),gcc编译器在编译的时候就知道a、b、c一定是整数类型,对于两个整数的相加那么编译器就可以选择整数版本作为编译的结果(虽然我不知道gcc到底有没有做),那么在运行的时候就省去了一个判断的过程。
相对的,对于如下的Python代码:

a = 1
b = 2
c = a + b

因为Python是动态类型,变量的类型只有在运行时才能确定其类型,上面的a + b这行代码在Python中执行时首先要判断a、b是否属于同一类型,如果不是因为Python属于强类型定义语言那么就会报TypeError: unsupported operand type(s) for +: 'int' and 'str'类似的错误。如果这两个变量是同一类型(整数),那么就会通过PyIntObject->PyObject_HEAD->ob_type获得对应整数类型的类型结构体PyInt_Type,然后再调用PyInt_Type->int_methods->int_add来进行两个整数的相加。这个过程是如此的”冗长”。

静态类型数据声明

在Cython中,无类型动态类型变量使用和Python中的变量用法一样,不需要指定类型。

而Cython中的静态类型数据需要使用关键字 cdef 来声明,比如:

cdef int i
cdef int j
cdef float k

声明多个静态类型变量:

def integrate(a, b, f):
    cdef:
        int i
        int N=2000
        float dx, s=0.0

Cython指针用法:

cdef double golden_ratio
cdef double *p_double
p_double = &golden_ratio
p_double[0] = 1.618
print golden_ratio
# => 1.618

不能通过 *p_double 来更改指针p_double指向 的变量的值,可以用上面索引(索引为0)的方式来访问。

st_t *p_st = make_struct();           (x)
int a_doubled = p_st->a + p_st->a;    (x)

cdef st_t *p_st = make_struct()
cdef int a_doubled = p_st.a + p_st.a

如果指针指向的是结构体的话,那么不能使用->的方式访问数据,只能使用.的方式来访问。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章