1.起因
衆所周知,python在處理一些計算量大的任務時效率很低,不僅僅是執行速率,還有內存佔用上,比如下面一段代碼就可以讓你的電腦卡得不行:
alist = [i for i in xrange(1024*1024*1024)]
所以有的時候還是得藉助C/C++來增強Python的效率。
2.方法
我所知道的大概有三種常用方法:
1>使用ctypes模塊來調用C寫的共享庫,比如:
#測試ctypes調用linux動態庫的能力
from ctypes import *
lib = CDLL("libc.so.6")
printf = lib.printf
printf("Hello World\n")
#查找動態庫
from ctypes.util import find_library
print find_library('c')
output = CDLL(find_library("c")).printf
output("測試成功!\n")
但是用它來調用C++寫的so就不太合適,因爲編譯時c++函數名修飾會給你的函數取一個特殊的字符串,你不能在你的python代碼裏直接使用此函數名,除非你使用的是修飾後的函數名。(在linux下你可以用nm來查看so中的函數名)
2>用C來寫python的擴展模塊,這個沒怎麼用過,以後使用時再記錄在此。
3>用C++來寫python擴展模塊:
我是使用Boost.Python來寫擴展的,先上工作中的代碼片段:
#include <boost/python.hpp> //包含boost.python頭文件
#include <cstdio>
#include <string>
using namespace boost::python;//引入命令空間
class lshw //定義一個類
{
public:
lshw();
virtual ~lshw();
void scan_device();
string get_xml();
private:
hwNode *computer;
};
lshw::lshw()
{
computer = new hwNode("computer", hw::system);
}
lshw::~lshw()
{
if (computer)
delete computer;
}
void lshw::scan_device()
{
enable("output:numeric");
disable("output:sanitize");
scan_system(*computer);
}
string lshw::get_xml()
{
return computer->asXML();
}
void hello()
{
std::cout << "Hello World!" <<std::endl;
}
BOOST_PYTHON_MODULE(lshw)
{
class_<lshw, boost::noncopyable > ("lshw", "This is a lshw project python extend", init<>())//導出類中的方法
.def("scan_device", &lshw::scan_device)
.def("get_xml", &lshw::get_xml)
;
def("hello",&hello);//導出方法
}
使用boost.python其實結構很簡單,你只要寫很少的boost.python的代碼,你可以把大部分的精力放在C++功能代碼上,花很少的精力就可以把它擴展成python的模塊。下面是我在Ubuntu11.10上的編譯過程:
首先安裝boost.python:
sudo apt-get install libboost-python1.46.1
再來編譯生成so共享庫文件:
g++ -shared -fPIC lshw.cc -o lshw.so -lboost_python
使用:
import lshw
hw = lshw.lshw()
lshw.hello()
hw.scan_device()
xml = self.hw.get_xml()
當然,lshw.so和你的py文件要讓在同一目錄下,或者你可以把它放在/usr/lib/python2.7/dist-packages/目錄下,你就可以在系統的任何地方加載它了。這段代碼僅僅是展示一下boost.python的使用方法,並沒有實際的意義,也無法編譯通過,只是一個簡單的模型。
1.總結
Boost.Python 是 Boost 的一個組件。而 Boost 是目前很紅火的準 C++ 標準庫,它提供了很多組件使得人們可以用 C++ 語言更方便地實現更多的功能。 Boost.Python 就是 Boost 衆多組件中的一個。但它是個特例,它的目的不是單純地增強 C++ 語言的功能,而是希望利用 C++ 語言來增強 Python 語言的能力。使用 Boost.Python 庫,我可以方便地將 C++ 語言寫的程序庫用於 Python 語言,可以用 Python 更好地完成更多的任務。