程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python進階系列(十三)

編輯:Python

目錄

For - Else

else從句

使用C擴展

CTypes


For - Else

循環是任何語言的一個必備要素。同樣地,for循環就是Python的一個重要組成部分。然而還有一些東西是初學者並不知道的。我們將一個個討論一下。

我們先從已經知道的開始。我們知道可以像這樣使用for循環:

fruits = ['apple', 'banana', 'mango']
for fruit in fruits:
    print(fruit.capitalize())

Output: Apple

        Banana

        Mango

這是一個for循環非常基礎的結構。現在我們繼續看看,Python的for循環的一些鮮為人所知的特性。

else從句

for循環還有一個else從句,我們大多數人並不熟悉。這個else從句會在循環正常結束時執行。這意味著,循環沒有遇到任何break. 一旦你掌握了何時何地使用它,它真的會非常有用。我自己對它真是相見恨晚。

有個常見的構造是跑一個循環,並查找一個元素。如果這個元素被找到了,我們使用break來中斷這個循環。有兩個場景會讓循環停下來。

  1. 第一個是當一個元素被找到,break被觸發。
  2. 第二個場景是循環結束。

現在我們也許想知道其中哪一個,才是導致循環完成的原因。一個方法是先設置⼀個標記,然後在循環結束時打上標記。另一個是使用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')

使用C擴展

CPython還為開發者實現了一個有趣的特性,使用Python可以輕松調用C代碼

開發者有三種方法可以在自己的Python代碼中來調用C編寫的函數ctypes,SWIG,Python/C API。每種方式也都有各自的利弊。

首先,我們要明確為什麼要在Python中調用C?

常見原因如下:

  1. 你要提升代碼的運行速度,而且你知道C要比Python快50倍以上
  2. C語言中有很多傳統類庫,而且有些正是你想要的,但你又不想用Python去重寫它們
  3. 想對從內存到文件接口這樣的底層資源進行訪問
  4. 不需要理由,就是想這樣做

CTypes

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中對對象進行操作。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved