Python:常用函數(shù)封裝:
創(chuàng)新互聯(lián)主要從事成都網(wǎng)站建設(shè)、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)平邑,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575
def is_chinese(uchar):
"""判斷一個(gè)unicode是否是漢字"""
if uchar = u'\u4e00' and uchar=u'\u9fa5':
return True
else:
return False
def is_number(uchar):
"""判斷一個(gè)unicode是否是數(shù)字"""
if uchar = u'\u0030' and uchar=u'\u0039':
return True
else:
return False
def is_alphabet(uchar):
"""判斷一個(gè)unicode是否是英文字母"""
if (uchar = u'\u0041' and uchar=u'\u005a') or (uchar = u'\u0061' and uchar=u'\u007a'):
return True
else:
return False
def is_other(uchar):
"""判斷是否非漢字,數(shù)字和英文字符"""
if not (is_chinese(uchar) or is_number(uchar) or is_alphabet(uchar)):
return True
else:
return False
def B2Q(uchar):
"""半角轉(zhuǎn)全角"""
inside_code=ord(uchar)
if inside_code0x0020 or inside_code0x7e: #不是半角字符就返回原來的字符
return uchar
if inside_code==0x0020: #除了空格其他的全角半角的公式為:半角=全角-0xfee0
inside_code=0x3000
else:
inside_code+=0xfee0
return unichr(inside_code)
def Q2B(uchar):
"""全角轉(zhuǎn)半角"""
inside_code=ord(uchar)
if inside_code==0x3000:
inside_code=0x0020
else:
inside_code-=0xfee0
if inside_code0x0020 or inside_code0x7e: #轉(zhuǎn)完之后不是半角字符返回原來的字符
return uchar
return unichr(inside_code)
def stringQ2B(ustring):
"""把字符串全角轉(zhuǎn)半角"""
return "".join([Q2B(uchar) for uchar in ustring])
def uniform(ustring):
"""格式化字符串,完成全角轉(zhuǎn)半角,大寫轉(zhuǎn)小寫的工作"""
return stringQ2B(ustring).lower()
def string2List(ustring):
"""將ustring按照中文,字母,數(shù)字分開"""
retList=[]
utmp=[]
for uchar in ustring:
if is_other(uchar):
if len(utmp)==0:
continue
else:
retList.append("".join(utmp))
utmp=[]
else:
utmp.append(uchar)
if len(utmp)!=0:
retList.append("".join(utmp))
return retList
在C語言中,字符串處理是每天都要面對(duì)的問題。我們都知道C語言中其實(shí)并沒有一種原生的字符串類型,‘字符串’在C語言里只是一種特殊的以''結(jié)尾的字符數(shù)組。因此,如何將C語言與更高層次的Python語言在‘字符串’處理這個(gè)問題上對(duì)接是一個(gè)有難度的問題。所幸有swig這種強(qiáng)大的工具。
如何封裝一個(gè)函數(shù),它修改參數(shù)字符串的內(nèi)容
假如有這樣一個(gè)C語言的函數(shù),
!-- lang: cpp --
void FillZero(char* pc,size_t * piLen)
{
size_t i=0;
while(i++*piLen/2 )
*pc++ = '0';
*pc = 0;
*piLen = i+1;
}
這個(gè)函數(shù)的功能是把字符串變成n個(gè)0。不過我們更關(guān)注函數(shù)的形式。這樣的函數(shù),表面上看char* pc是函數(shù)的參數(shù),可是實(shí)際上它才是函數(shù)的返回值和執(zhí)行的結(jié)果。piLen這個(gè)參數(shù)既是pc的最大長度,也是新的字符串的長度。我們直接用python封裝,看看運(yùn)行結(jié)果。
Type "help", "copyright", "credits" or "license" for more information.
import cchar
s='123456'
cchar.FillZero(s,6)
Traceback (most recent call last):
File "stdin", line 1, in module
TypeError: in method 'FillZero', argument 2 of type 'size_t *'
結(jié)果差強(qiáng)人意,不是我們想要得到的結(jié)果。函數(shù)的第二個(gè)參數(shù)為size_t* 我們很難用python來表示,而且python中也不存在既是輸入,也是輸出的參數(shù)。
swig有一個(gè)標(biāo)準(zhǔn)庫,其中有一個(gè)cstring.i文件就是用來解決C語言字符串類型的問題。
我們?cè)?i文件中加入這樣幾行
!-- lang: cpp --
%include "cstring.i"
%cstring_output_withsize(char* pc,size_t* pi)
void FillZero(char* pc, size_t* pi);
然后運(yùn)行看結(jié)果
Type "help", "copyright", "credits" or "license" for more information.
import cchar
cchar.FillZero(10)
'00000\x00'
s=cchar.FillZero(10)
print s
00000
我們看函數(shù)的變化。首先在python里, FillZero變成了只有一個(gè)參數(shù)的函數(shù)。然后函數(shù)的返回值變成了一個(gè)字符串。其實(shí)cstring_output_size其實(shí)是一個(gè)宏,通過這個(gè)宏的定義改變了函數(shù)的形式,直接在Python中得到我們想要的結(jié)果。
其實(shí)類似cstring_output_size的宏還有好幾個(gè),我列舉一下:
cstring_output_allocate(char *s,free($1));
第一個(gè)參數(shù)是指向字符串地址的指針,第二個(gè)參數(shù)為釋放空間的方法。
大家考慮這一下這樣的函數(shù):
void foo(char* s)
{
s = (char*)malloc(10);
memcpy(s,"123456789",9);
}
s這個(gè)參數(shù)表面上看是輸入,實(shí)際上是函數(shù)真正的輸出。 函數(shù)中真正改變的東西是chars指向的字符串的值。而且char這個(gè)類型,
python或者其他腳本語言里應(yīng)該都沒有對(duì)應(yīng)的類型。那么我們用cstring_output_allocate將這個(gè)函數(shù)轉(zhuǎn)換成另外一個(gè)形式的python或者其他腳本語言的函數(shù)。轉(zhuǎn)換后的函數(shù)其實(shí)是這樣的,以python為例str
foo()。
!-- lang: cpp --
%module a
%include "cstring.i"
%{
void foo(char* s);
%}
%cstring_output_allocate(char *s, free(*$1));
void foo(char *s);
在python中的調(diào)用:
!-- lang: python --
import a
a.foo()
'123456789'
cstring_output_maxsize(char *path, int maxpath);
第一個(gè)參數(shù)也是可以改變的字符串首地址,第二個(gè)參數(shù)為字符串的最大長度。在Python中調(diào)用的時(shí)候,只有maxpath這個(gè)參數(shù),返回字符串。
cstring_output_allocate(char *s, free($1));
第一個(gè)參數(shù)為指向字符串首地址的指針,第二個(gè)參數(shù)為釋放指針的方法。這個(gè)宏主要是封裝一種直接在函數(shù)內(nèi)部malloc空間的函數(shù)。在Python中調(diào)用時(shí)沒有參數(shù),直接返回字符串。
cstring_output_allocate_size(char *s, int slen, free(*$1));
這個(gè)相當(dāng)于前面兩個(gè)函數(shù)的組合。在函數(shù)內(nèi)部malloc空間,然后將字符串長度通過slen返回。其實(shí)在調(diào)用的時(shí)候非常簡單,沒有參數(shù),直接返回字符串。
如何處理c++的std::string
std::string是C++標(biāo)準(zhǔn)類庫STL中常見的類。在平時(shí)工作中大家肯定是沒少用。在python中如何封裝std::string? swig提供了標(biāo)準(zhǔn)庫
例如函數(shù):
!-- lang: cpp --
string Repeat(const string s)
{
return s+s;
}
只要在swig中加入這樣幾行:
!-- lang: cpp --
%include "std_string.i"
using namespace std;
string Repeat(const string s);
運(yùn)行結(jié)果:
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import cchar
cchar.Repeat('123')
'123123'
使用起來很方便,但需要注意的是,假如函數(shù)的參數(shù)的內(nèi)容是可以被修改,就不能用這種方式封裝。
例如:
!-- lang: cpp --
void repeat(string s)
{
s+=s;
}
這樣的函數(shù)直接使用 'std_string.i' 就是無效的。遇到這種函數(shù),只能用C語言封裝成 void repeat(chars, int maxsize), 再用swig調(diào)用 'cstring_output_withsize' 這個(gè)宏再封裝一次了。
可以定義一個(gè)類,類里定義很多函數(shù)(主要用它做什么)或直接定義函數(shù)在一個(gè)py文件中
在另一個(gè)文件中導(dǎo)入這個(gè)那個(gè)py包,調(diào)用類和方法
就是封裝了
1、高階函數(shù)
變量可以指向函數(shù),函數(shù)的參數(shù)可以接收變量,那么函數(shù)可以接收另一個(gè)函數(shù)作為參數(shù),這種函數(shù)稱為高階函數(shù)。
(1)把函數(shù)作為實(shí)參
(2)把函數(shù)作為返回值
2、系統(tǒng)的內(nèi)置高階函數(shù)
(1)map函數(shù):接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是序列,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并且把結(jié)果作為新的列表返回
(2)reduce函數(shù):把一個(gè)函數(shù)作用到一個(gè)序列上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce把結(jié)果和序列的下一個(gè)元素做累積計(jì)算
(3)filter函數(shù):也接收一個(gè)函數(shù)和一個(gè)序列,和map函數(shù)不同的是,filter函數(shù)把傳入的函數(shù)依次作用于每個(gè)元素,然后返回返回值是True的元素
(4)sorted函數(shù):排序函數(shù)
把用戶名按照首字母不區(qū)分大小寫排序
(5)sorted()函數(shù)按照關(guān)鍵字排序
關(guān)鍵字:商品個(gè)數(shù)
(6)sorted()函數(shù)按照關(guān)鍵字排序,用鍵值來查找
(7)lambda匿名函數(shù):有時(shí)候傳參數(shù)時(shí)不需要顯示自定義的函數(shù),直接傳入匿名函數(shù)更方便;冒號(hào)前面的x,y表示函數(shù)參數(shù),匿名函數(shù)不需要擔(dān)心函數(shù)名的沖突,匿名函數(shù)也是一個(gè)函數(shù)對(duì)象,可以把匿名函數(shù)賦值給一個(gè)變量,再利用變量來調(diào)用函數(shù),匿名函數(shù)也可以作為返回值返回
3、高階函數(shù)的應(yīng)用:
(1)sorted函數(shù):
(2)sorted函數(shù)默認(rèn)是從小到大排序
4、裝飾器
裝飾器就是用來裝飾函數(shù)的:想要增加原有函數(shù)的功能,但是不希望修改原有函數(shù)的定義,在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式
(1)此裝飾器的功能:計(jì)算函數(shù)的運(yùn)行時(shí)間
import functools
@functools.wraps(f)? ?##保留原有函數(shù)的屬性
運(yùn)行結(jié)果:
(2)此裝飾器的功能:用戶登錄認(rèn)證
運(yùn)行結(jié)果:
(3)此裝飾器的功能:認(rèn)證用戶的同時(shí),顯示用戶的轉(zhuǎn)賬金額
import inspect
inspect.getcallargs()將傳的參數(shù)封裝為一個(gè)字典,字典的key值是形式參數(shù),value值是實(shí)參
(4)此裝飾器的功能:確保收到的每個(gè)參數(shù)都是整數(shù),是整數(shù)就求和,否則拋出錯(cuò)誤
(5)此裝飾器的功能:給裝飾器傳參數(shù),是整數(shù)和浮點(diǎn)數(shù)就求和
python學(xué)習(xí)網(wǎng),大量的免費(fèi)python視頻教程,歡迎在線學(xué)習(xí)!
封裝其實(shí)分為兩個(gè)層面,但無論哪種層面的封裝,都要對(duì)外界提供好訪問你內(nèi)部隱藏內(nèi)容的接口(接口可以理解為入口,有了這個(gè)入口,使用者無需且不能夠直接訪問到內(nèi)部隱藏的細(xì)節(jié),只能走接口,并且我們可以在接口的實(shí)現(xiàn)上附加更多的處理邏輯,從而嚴(yán)格控制使用者的訪問)
第一個(gè)層面的封裝(什么都不用做):創(chuàng)建類和對(duì)象會(huì)分別創(chuàng)建二者的名稱空間,我們只能用類名.或者obj.的方式去訪問里面的名字,這本身就是一種封裝。print(m1.brand) #實(shí)例化對(duì)象(m1.)
print(motor_vehicle.tag) #類名(motor_vehicle.)
-------------輸出結(jié)果---------注意:對(duì)于這一層面的封裝(隱藏),類名.和實(shí)例名.就是訪問隱藏屬性的接口
第二個(gè)層面的封裝:類中把某些屬性和方法隱藏起來(或者說定義成私有的),只在類的內(nèi)部使用、外部無法訪問,或者留下少量接口(函數(shù))供外部訪問。
Python中私有化的方法也比較簡單,即在準(zhǔn)備私有化的屬性(包括方法、數(shù)據(jù))名字前面加兩個(gè)下劃線即可。
文章標(biāo)題:Python封裝高函數(shù) python封裝成函數(shù)
URL分享:http://redsoil1982.com.cn/article36/dodjosg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、關(guān)鍵詞優(yōu)化、網(wǎng)站導(dǎo)航、網(wǎng)站制作、響應(yīng)式網(wǎng)站、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)