目錄
For - Else
else從句
使用C擴展
CTypes
循環是任何語言的一個必備要素。同樣地,for循環就是Python的一個重要組成部分。然而還有一些東西是初學者並不知道的。我們將一個個討論一下。
我們先從已經知道的開始。我們知道可以像這樣使用for循環:
fruits = ['apple', 'banana', 'mango']
for fruit in fruits:
print(fruit.capitalize())
Output: Apple
Banana
Mango
這是一個for循環非常基礎的結構。現在我們繼續看看,Python的for循環的一些鮮為人所知的特性。
for循環還有一個else從句,我們大多數人並不熟悉。這個else從句會在循環正常結束時執行。這意味著,循環沒有遇到任何break. 一旦你掌握了何時何地使用它,它真的會非常有用。我自己對它真是相見恨晚。
有個常見的構造是跑一個循環,並查找一個元素。如果這個元素被找到了,我們使用break來中斷這個循環。有兩個場景會讓循環停下來。
現在我們也許想知道其中哪一個,才是導致循環完成的原因。一個方法是先設置⼀個標記,然後在循環結束時打上標記。另一個是使用else從句。
這就是for/else循環的基本結構:
for item in container:
if search_something(item):
# Found it!
process(item)
break
else:
# Didn't find anything..
not_found_in_container()
考慮下這個簡單的案例,它是我從官方文檔裡拿來的:
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, 'equals', x, '*', n/x)
break
它會找出2到10之間的數字的因子。現在是趣味環節了。我們可以加上一個附加的else語句塊,來抓住質數,並且告訴我們:
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print( n, 'equals', x, '*', n/x)
break
else:
# loop fell through without finding a factor
print(n, 'is a prime number')
CPython還為開發者實現了一個有趣的特性,使用Python可以輕松調用C代碼
開發者有三種方法可以在自己的Python代碼中來調用C編寫的函數ctypes,SWIG,Python/C API。每種方式也都有各自的利弊。
首先,我們要明確為什麼要在Python中調用C?
常見原因如下:
Python中的ctypes模塊可能是Python調用C方法中最簡單的一種。ctypes模塊提供了和C語言兼容的數據類型和函數來加載dll文件,因此在調用時不需對源文件做任何的修改。也正是如此奠定了這種方法的簡單性。
示例如下
實現兩數求和的C代碼,保存為add.c
//sample C file to add 2 numbers - int and floats
#include <stdio.h>
int add_int(int, int);
float add_float(float, float);
int add_int(int num1, int num2){
return num1 + num2;
}
float add_float(float num1, float num2){
return num1 + num2;
}
接下來將C文件編譯為.so文件(windows下為DLL)。下面操作會生成adder.so文件
#For Linux
$ gcc -shared -Wl,-soname,adder -o adder.so -fPIC add.c
#For Mac
$ gcc -shared -Wl,-install_name,adder.so -o adder.so -fPIC add.c
現在在你的Python代碼中來調用它
from ctypes import *
#load the shared object file
adder = CDLL('./adder.so')
#Find sum of integers
res_int = adder.add_int(4,5)
print "Sum of 4 and 5 = " + str(res_int)
#Find sum of floats
a = c_float(5.5)
b = c_float(4.1)
add_float = adder.add_float
add_float.restype = c_float
print "Sum of 5.5 and 4.1 = ", str(add_float(a, b))
輸出如下:
Sum of 4 and 5 = 9
Sum of 5.5 and 4.1 = 9.60000038147
在這個例子中,C文件是自解釋的,它包含兩個函數,分別實現了整形求和和浮點型求和。
在Python文件中,一開始先導入ctypes模塊,然後使用CDLL函數來加載我們創建的庫文件。這樣我們就可以通過變量adder來使用C類庫中的函數了。當adder.add_int()被調用時,內部將發起一個對C函數add_int的調用。ctypes接口允許我們在調用C函數時使用原生Python中默認的字符串型和整型。
而對於其他類似布爾型和浮點型這樣的類型,必須要使用正確的ctype類型才可以。如向adder.add_float()函數傳參時, 我們要先將Python中的十進制值轉化為c_float類型,然後才能傳送給C函數。這種方法雖然簡單,清晰,但是卻很受限。例如,並不能在C中對對象進行操作。