Python 函數(shù)
創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比梨樹網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式梨樹網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋梨樹地區(qū)。費(fèi)用合理售后完善,十多年實(shí)體公司更值得信賴。
函數(shù)是組織好的,可重復(fù)使用的,用來實(shí)現(xiàn)單一,或相關(guān)聯(lián)功能的代碼段。
函數(shù)能提高應(yīng)用的模塊性,和代碼的重復(fù)利用率。你已經(jīng)知道Python提供了許多內(nèi)建函數(shù),比如print()。但你也可以自己創(chuàng)建函數(shù),這被叫做用戶自定義函數(shù)。
定義一個(gè)函數(shù)
你可以定義一個(gè)由自己想要功能的函數(shù),以下是簡單的規(guī)則:
函數(shù)代碼塊以?def?關(guān)鍵詞開頭,后接函數(shù)標(biāo)識(shí)符名稱和圓括號(hào)()。
任何傳入?yún)?shù)和自變量必須放在圓括號(hào)中間。圓括號(hào)之間可以用于定義參數(shù)。
函數(shù)的第一行語句可以選擇性地使用文檔字符串—用于存放函數(shù)說明。
函數(shù)內(nèi)容以冒號(hào)起始,并且縮進(jìn)。
return [表達(dá)式]?結(jié)束函數(shù),選擇性地返回一個(gè)值給調(diào)用方。不帶表達(dá)式的return相當(dāng)于返回 None。
語法
def functionname( parameters ): ? "函數(shù)_文檔字符串"
function_suite
return [expression]
默認(rèn)情況下,參數(shù)值和參數(shù)名稱是按函數(shù)聲明中定義的順序匹配起來的。
實(shí)例
以下為一個(gè)簡單的Python函數(shù),它將一個(gè)字符串作為傳入?yún)?shù),再打印到標(biāo)準(zhǔn)顯示設(shè)備上。
實(shí)例(Python 2.0+)
def printme( str ): ? "打印傳入的字符串到標(biāo)準(zhǔn)顯示設(shè)備上"
print str
return
函數(shù)調(diào)用
定義一個(gè)函數(shù)只給了函數(shù)一個(gè)名稱,指定了函數(shù)里包含的參數(shù),和代碼塊結(jié)構(gòu)。
這個(gè)函數(shù)的基本結(jié)構(gòu)完成以后,你可以通過另一個(gè)函數(shù)調(diào)用執(zhí)行,也可以直接從Python提示符執(zhí)行。
如下實(shí)例調(diào)用了printme()函數(shù):
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 定義函數(shù)def printme( str ): ? "打印任何傳入的字符串"
print str
return
# 調(diào)用函數(shù)printme("我要調(diào)用用戶自定義函數(shù)!")printme("再次調(diào)用同一函數(shù)")
以上實(shí)例輸出結(jié)果:
我要調(diào)用用戶自定義函數(shù)!再次調(diào)用同一函數(shù)
參數(shù)傳遞
在 python 中,類型屬于對(duì)象,變量是沒有類型的:
a=[1,2,3]
a="Runoob"
以上代碼中,[1,2,3]?是 List 類型,"Runoob"?是 String 類型,而變量 a 是沒有類型,她僅僅是一個(gè)對(duì)象的引用(一個(gè)指針),可以是 List 類型對(duì)象,也可以指向 String 類型對(duì)象。
可更改(mutable)與不可更改(immutable)對(duì)象
在 python 中,strings, tuples, 和 numbers 是不可更改的對(duì)象,而 list,dict 等則是可以修改的對(duì)象。
不可變類型:變量賦值?a=5?后再賦值?a=10,這里實(shí)際是新生成一個(gè) int 值對(duì)象 10,再讓 a 指向它,而 5 被丟棄,不是改變a的值,相當(dāng)于新生成了a。
可變類型:變量賦值?la=[1,2,3,4]?后再賦值?la[2]=5?則是將 list la 的第三個(gè)元素值更改,本身la沒有動(dòng),只是其內(nèi)部的一部分值被修改了。
python 函數(shù)的參數(shù)傳遞:
不可變類型:類似 c++ 的值傳遞,如 整數(shù)、字符串、元組。如fun(a),傳遞的只是a的值,沒有影響a對(duì)象本身。比如在 fun(a)內(nèi)部修改 a 的值,只是修改另一個(gè)復(fù)制的對(duì)象,不會(huì)影響 a 本身。
可變類型:類似 c++ 的引用傳遞,如 列表,字典。如 fun(la),則是將 la 真正的傳過去,修改后fun外部的la也會(huì)受影響
python 中一切都是對(duì)象,嚴(yán)格意義我們不能說值傳遞還是引用傳遞,我們應(yīng)該說傳不可變對(duì)象和傳可變對(duì)象。
python 傳不可變對(duì)象實(shí)例
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
def ChangeInt( a ): ? ?a = 10
b = 2ChangeInt(b)print b # 結(jié)果是 2
實(shí)例中有 int 對(duì)象 2,指向它的變量是 b,在傳遞給 ChangeInt 函數(shù)時(shí),按傳值的方式復(fù)制了變量 b,a 和 b 都指向了同一個(gè) Int 對(duì)象,在 a=10 時(shí),則新生成一個(gè) int 值對(duì)象 10,并讓 a 指向它。
傳可變對(duì)象實(shí)例
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫函數(shù)說明def changeme( mylist ): ? "修改傳入的列表"
mylist.append([1,2,3,4])
print "函數(shù)內(nèi)取值: ", mylist
return
# 調(diào)用changeme函數(shù)mylist = [10,20,30]changeme( mylist )print "函數(shù)外取值: ", mylist
實(shí)例中傳入函數(shù)的和在末尾添加新內(nèi)容的對(duì)象用的是同一個(gè)引用,故輸出結(jié)果如下:
函數(shù)內(nèi)取值: ?[10, 20, 30, [1, 2, 3, 4]]函數(shù)外取值: ?[10, 20, 30, [1, 2, 3, 4]]
參數(shù)
以下是調(diào)用函數(shù)時(shí)可使用的正式參數(shù)類型:
必備參數(shù)
關(guān)鍵字參數(shù)
默認(rèn)參數(shù)
不定長參數(shù)
必備參數(shù)
必備參數(shù)須以正確的順序傳入函數(shù)。調(diào)用時(shí)的數(shù)量必須和聲明時(shí)的一樣。
調(diào)用printme()函數(shù),你必須傳入一個(gè)參數(shù),不然會(huì)出現(xiàn)語法錯(cuò)誤:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫函數(shù)說明def printme( str ): ? "打印任何傳入的字符串"
print str
return
#調(diào)用printme函數(shù)printme()
以上實(shí)例輸出結(jié)果:
Traceback (most recent call last):
File "test.py", line 11, in module
printme()TypeError: printme() takes exactly 1 argument (0 given)
關(guān)鍵字參數(shù)
關(guān)鍵字參數(shù)和函數(shù)調(diào)用關(guān)系緊密,函數(shù)調(diào)用使用關(guān)鍵字參數(shù)來確定傳入的參數(shù)值。
使用關(guān)鍵字參數(shù)允許函數(shù)調(diào)用時(shí)參數(shù)的順序與聲明時(shí)不一致,因?yàn)?Python 解釋器能夠用參數(shù)名匹配參數(shù)值。
以下實(shí)例在函數(shù) printme() 調(diào)用時(shí)使用參數(shù)名:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫函數(shù)說明def printme( str ): ? "打印任何傳入的字符串"
print str
return
#調(diào)用printme函數(shù)printme( str = "My string")
以上實(shí)例輸出結(jié)果:
My string
下例能將關(guān)鍵字參數(shù)順序不重要展示得更清楚:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫函數(shù)說明def printinfo( name, age ): ? "打印任何傳入的字符串"
print "Name: ", name
print "Age ", age
return
#調(diào)用printinfo函數(shù)printinfo( age=50, name="miki" )
以上實(shí)例輸出結(jié)果:
Name: ?mikiAge ?50
默認(rèn)參數(shù)
調(diào)用函數(shù)時(shí),默認(rèn)參數(shù)的值如果沒有傳入,則被認(rèn)為是默認(rèn)值。下例會(huì)打印默認(rèn)的age,如果age沒有被傳入:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
#可寫函數(shù)說明def printinfo( name, age = 35 ): ? "打印任何傳入的字符串"
print "Name: ", name
print "Age ", age
return
#調(diào)用printinfo函數(shù)printinfo( age=50, name="miki" )printinfo( name="miki" )
以上實(shí)例輸出結(jié)果:
Name: ?mikiAge ?50Name: ?mikiAge ?35
不定長參數(shù)
你可能需要一個(gè)函數(shù)能處理比當(dāng)初聲明時(shí)更多的參數(shù)。這些參數(shù)叫做不定長參數(shù),和上述2種參數(shù)不同,聲明時(shí)不會(huì)命名。基本語法如下:
def functionname([formal_args,] *var_args_tuple ): ? "函數(shù)_文檔字符串"
function_suite
return [expression]
加了星號(hào)(*)的變量名會(huì)存放所有未命名的變量參數(shù)。不定長參數(shù)實(shí)例如下:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫函數(shù)說明def printinfo( arg1, *vartuple ): ? "打印任何傳入的參數(shù)"
print "輸出: "
print arg1
for var in vartuple: ? ? ?print var
return
# 調(diào)用printinfo 函數(shù)printinfo( 10 )printinfo( 70, 60, 50 )
以上實(shí)例輸出結(jié)果:
輸出:10輸出:706050
匿名函數(shù)
python 使用 lambda 來創(chuàng)建匿名函數(shù)。
lambda只是一個(gè)表達(dá)式,函數(shù)體比def簡單很多。
lambda的主體是一個(gè)表達(dá)式,而不是一個(gè)代碼塊。僅僅能在lambda表達(dá)式中封裝有限的邏輯進(jìn)去。
lambda函數(shù)擁有自己的命名空間,且不能訪問自有參數(shù)列表之外或全局命名空間里的參數(shù)。
雖然lambda函數(shù)看起來只能寫一行,卻不等同于C或C++的內(nèi)聯(lián)函數(shù),后者的目的是調(diào)用小函數(shù)時(shí)不占用棧內(nèi)存從而增加運(yùn)行效率。
語法
lambda函數(shù)的語法只包含一個(gè)語句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
如下實(shí)例:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫函數(shù)說明sum = lambda arg1, arg2: arg1 + arg2
# 調(diào)用sum函數(shù)print "相加后的值為 : ", sum( 10, 20 )print "相加后的值為 : ", sum( 20, 20 )
以上實(shí)例輸出結(jié)果:
相加后的值為 : ?30相加后的值為 : ?40
return 語句
return語句[表達(dá)式]退出函數(shù),選擇性地向調(diào)用方返回一個(gè)表達(dá)式。不帶參數(shù)值的return語句返回None。之前的例子都沒有示范如何返回?cái)?shù)值,下例便告訴你怎么做:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
# 可寫函數(shù)說明def sum( arg1, arg2 ): ? # 返回2個(gè)參數(shù)的和."
total = arg1 + arg2
print "函數(shù)內(nèi) : ", total
return total
# 調(diào)用sum函數(shù)total = sum( 10, 20 )
以上實(shí)例輸出結(jié)果:
函數(shù)內(nèi) : ?30
變量作用域
一個(gè)程序的所有的變量并不是在哪個(gè)位置都可以訪問的。訪問權(quán)限決定于這個(gè)變量是在哪里賦值的。
變量的作用域決定了在哪一部分程序你可以訪問哪個(gè)特定的變量名稱。兩種最基本的變量作用域如下:
全局變量
局部變量
全局變量和局部變量
定義在函數(shù)內(nèi)部的變量擁有一個(gè)局部作用域,定義在函數(shù)外的擁有全局作用域。
局部變量只能在其被聲明的函數(shù)內(nèi)部訪問,而全局變量可以在整個(gè)程序范圍內(nèi)訪問。調(diào)用函數(shù)時(shí),所有在函數(shù)內(nèi)聲明的變量名稱都將被加入到作用域中。如下實(shí)例:
實(shí)例(Python 2.0+)
#!/usr/bin/python# -*- coding: UTF-8 -*-
total = 0 # 這是一個(gè)全局變量# 可寫函數(shù)說明def sum( arg1, arg2 ): ? #返回2個(gè)參數(shù)的和."
total = arg1 + arg2 # total在這里是局部變量.
print "函數(shù)內(nèi)是局部變量 : ", total
return total
#調(diào)用sum函數(shù)sum( 10, 20 )print "函數(shù)外是全局變量 : ", total
以上實(shí)例輸出結(jié)果:
函數(shù)內(nèi)是局部變量 : ?30函數(shù)外是全局變量 : ?0
python 的函數(shù)參數(shù)類型分為4種:
1.位置參數(shù):調(diào)用函數(shù)時(shí)根據(jù)函數(shù)定義的參數(shù)位置來傳遞參數(shù),位置參數(shù)也可以叫做必要參數(shù),函數(shù)調(diào)用時(shí)必須要傳的參數(shù)。
當(dāng)參數(shù)滿足函數(shù)必要參數(shù)傳參的條件,函數(shù)能夠正常執(zhí)行:
add(1,2) #兩個(gè)參數(shù)的順序必須一一對(duì)應(yīng),且少一個(gè)參數(shù)都不可以
當(dāng)我們運(yùn)行上面的程序,輸出:
當(dāng)函數(shù)需要兩個(gè)必要參數(shù),但是調(diào)用函數(shù)只給了一個(gè)參數(shù)時(shí),程序會(huì)拋出異常
add(1)
當(dāng)我們運(yùn)行上面的程序,輸出:
當(dāng)函數(shù)需要兩個(gè)必要參數(shù),但是調(diào)用函數(shù)只給了三個(gè)參數(shù)時(shí),程序會(huì)拋出異常
add(1,2,3)
當(dāng)我們運(yùn)行上面的程序,輸出
2.關(guān)鍵字參數(shù):用于函數(shù)調(diào)用,通過“鍵-值”形式加以指定??梢宰尯瘮?shù)更加清晰、容易使用,同時(shí)也清除了參數(shù)的順序需求。
add(1,2) # 這種方式傳參,必須按順序傳參:x對(duì)應(yīng)1,y對(duì)應(yīng):2
add(y=2,x=1) #以關(guān)健字方式傳入?yún)?shù)(可以不按順序)
正確的調(diào)用方式
add(x=1, y=2)
add(y=2, x=1)
add(1, y=2)
以上調(diào)用方式都是允許的,能夠正常執(zhí)行
錯(cuò)誤的調(diào)用方式
add(x=1, 2)
add(y=2, 1)
以上調(diào)用都會(huì)拋出SyntaxError 異常
上面例子可以看出:有位置參數(shù)時(shí),位置參數(shù)必須在關(guān)鍵字參數(shù)的前面,但關(guān)鍵字參數(shù)之間不存在先后順序的
3.默認(rèn)參數(shù):用于定義函數(shù),為參數(shù)提供默認(rèn)值,調(diào)用函數(shù)時(shí)可傳可不傳該默認(rèn)參數(shù)的值,所有位置參數(shù)必須出現(xiàn)在默認(rèn)參數(shù)前,包括函數(shù)定義和調(diào)用,有多個(gè)默認(rèn)參數(shù)時(shí),調(diào)用的時(shí)候,既可以按順序提供默認(rèn)參數(shù),也可以不按順序提供部分默認(rèn)參數(shù)。當(dāng)不按順序提供部分默認(rèn)參數(shù)時(shí),需要把參數(shù)名寫上
默認(rèn)參數(shù)的函數(shù)定義
上面示例第一個(gè)是正確的定義位置參數(shù)的方式,第二個(gè)是錯(cuò)誤的,因?yàn)槲恢脜?shù)在前,默認(rèn)參數(shù)在后
def add1(x=1,y) 的定義會(huì)拋出如下異常
默認(rèn)參數(shù)的函數(shù)調(diào)用
注意:定義默認(rèn)參數(shù)默認(rèn)參數(shù)最好不要定義為可變對(duì)象,容易掉坑
不可變對(duì)象:該對(duì)象所指向的內(nèi)存中的值不能被改變,int,string,float,tuple
可變對(duì)象,該對(duì)象所指向的內(nèi)存中的值可以被改變,dict,list
這里只要理解一下這個(gè)概念就行或者自行百度,后續(xù)會(huì)寫相關(guān)的專題文章講解
舉一個(gè)簡單示例
4.可變參數(shù)區(qū)別:定義函數(shù)時(shí),有時(shí)候我們不確定調(diào)用的時(shí)候會(huì)多少個(gè)參數(shù),j就可以使用可變參數(shù)
可變參數(shù)主要有兩類:
*args: (positional argument) 允許任意數(shù)量的可選位置參數(shù)(參數(shù)),將被分配給一個(gè)元組, 參數(shù)名前帶*,args只是約定俗成的變量名,可以替換其他名稱
**kwargs:(keyword argument) 允許任意數(shù)量的可選關(guān)鍵字參數(shù),,將被分配給一個(gè)字典,參數(shù)名前帶**,kwargs只是約定俗成的變量名,可以替換其他名稱
*args 的用法
args 是用來傳遞一個(gè)非鍵值對(duì)的可變數(shù)量的參數(shù)列表給函數(shù)
語法是使用 符號(hào)的數(shù)量可變的參數(shù); 按照慣例,通常是使用arg這個(gè)單詞,args相當(dāng)于一個(gè)變量名,可以自己定義的
在上面的程序中,我們使用* args作為一個(gè)可變長度參數(shù)列表傳遞給add()函數(shù)。 在函數(shù)中,我們有一個(gè)循環(huán)實(shí)現(xiàn)傳遞的參數(shù)計(jì)算和輸出結(jié)果。
還可以直接傳遞列表或者數(shù)組的方式傳遞參數(shù),以數(shù)組或者列表方式傳遞參數(shù)名前面加(*) 號(hào)
理解* * kwargs
**kwargs 允許你將不定長度的鍵值對(duì), 作為參數(shù)傳遞給函數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)dict
下篇詳細(xì)講解 *args, **kwargs 的參數(shù)傳遞和使用敬請(qǐng)關(guān)注
1.常用內(nèi)置函數(shù):(不用import就可以直接使用)
help(obj) 在線幫助, obj可是任何類型
callable(obj) 查看一個(gè)obj是不是可以像函數(shù)一樣調(diào)用
repr(obj) 得到obj的表示字符串,可以利用這個(gè)字符串eval重建該對(duì)象的一個(gè)拷貝
eval_r(str) 表示合法的python表達(dá)式,返回這個(gè)表達(dá)式
dir(obj) 查看obj的name space中可見的name
hasattr(obj,name) 查看一個(gè)obj的name space中是否有name
getattr(obj,name) 得到一個(gè)obj的name space中的一個(gè)name
setattr(obj,name,value) 為一個(gè)obj的name space中的一個(gè)name指向vale這個(gè)object
delattr(obj,name) 從obj的name space中刪除一個(gè)name
vars(obj) 返回一個(gè)object的name space。用dictionary表示
locals() 返回一個(gè)局部name space,用dictionary表示
globals() 返回一個(gè)全局name space,用dictionary表示
type(obj) 查看一個(gè)obj的類型
isinstance(obj,cls) 查看obj是不是cls的instance
issubclass(subcls,supcls) 查看subcls是不是supcls的子類
類型轉(zhuǎn)換函數(shù)
chr(i) 把一個(gè)ASCII數(shù)值,變成字符
ord(i) 把一個(gè)字符或者unicode字符,變成ASCII數(shù)值
oct(x) 把整數(shù)x變成八進(jìn)制表示的字符串
hex(x) 把整數(shù)x變成十六進(jìn)制表示的字符串
str(obj) 得到obj的字符串描述
list(seq) 把一個(gè)sequence轉(zhuǎn)換成一個(gè)list
tuple(seq) 把一個(gè)sequence轉(zhuǎn)換成一個(gè)tuple
dict(),dict(list) 轉(zhuǎn)換成一個(gè)dictionary
int(x) 轉(zhuǎn)換成一個(gè)integer
long(x) 轉(zhuǎn)換成一個(gè)long interger
float(x) 轉(zhuǎn)換成一個(gè)浮點(diǎn)數(shù)
complex(x) 轉(zhuǎn)換成復(fù)數(shù)
max(...) 求最大值
min(...) 求最小值
用于執(zhí)行程序的內(nèi)置函數(shù)
complie 如果一段代碼經(jīng)常要使用,那么先編譯,再運(yùn)行會(huì)更快。
2.和操作系統(tǒng)相關(guān)的調(diào)用
系統(tǒng)相關(guān)的信息模塊 import sys
sys.argv是一個(gè)list,包含所有的命令行參數(shù).
sys.stdout sys.stdin sys.stderr 分別表示標(biāo)準(zhǔn)輸入輸出,錯(cuò)誤輸出的文件對(duì)象.
sys.stdin.readline() 從標(biāo)準(zhǔn)輸入讀一行 sys.stdout.write("a") 屏幕輸出a
sys.exit(exit_code) 退出程序
sys.modules 是一個(gè)dictionary,表示系統(tǒng)中所有可用的module
sys.platform 得到運(yùn)行的操作系統(tǒng)環(huán)境
sys.path 是一個(gè)list,指明所有查找module,package的路徑.
操作系統(tǒng)相關(guān)的調(diào)用和操作 import os
os.environ 一個(gè)dictionary 包含環(huán)境變量的映射關(guān)系 os.environ["HOME"] 可以得到環(huán)境變量HOME的值
os.chdir(dir) 改變當(dāng)前目錄 os.chdir('d:\\outlook') 注意windows下用到轉(zhuǎn)義
os.getcwd() 得到當(dāng)前目錄
os.getegid() 得到有效組id os.getgid() 得到組id
os.getuid() 得到用戶id os.geteuid() 得到有效用戶id
os.setegid os.setegid() os.seteuid() os.setuid()
os.getgruops() 得到用戶組名稱列表
os.getlogin() 得到用戶登錄名稱
os.getenv 得到環(huán)境變量
os.putenv 設(shè)置環(huán)境變量
os.umask 設(shè)置umask
os.system(cmd) 利用系統(tǒng)調(diào)用,運(yùn)行cmd命令
操作舉例:
os.mkdir('/tmp/xx') os.system("echo 'hello' /tmp/xx/a.txt") os.listdir('/tmp/xx')
os.rename('/tmp/xx/a.txt','/tmp/xx/b.txt') os.remove('/tmp/xx/b.txt') os.rmdir('/tmp/xx')
用python編寫一個(gè)簡單的shell
#!/usr/bin/python
import os, sys
cmd = sys.stdin.readline()
while cmd:
os.system(cmd)
cmd = sys.stdin.readline()
用os.path編寫平臺(tái)無關(guān)的程序
os.path.abspath("1.txt") == os.path.join(os.getcwd(), "1.txt")
os.path.split(os.getcwd()) 用于分開一個(gè)目錄名稱中的目錄部分和文件名稱部分。
os.path.join(os.getcwd(), os.pardir, 'a', 'a.doc') 全成路徑名稱.
os.pardir 表示當(dāng)前平臺(tái)下上一級(jí)目錄的字符 ..
os.path.getctime("/root/1.txt") 返回1.txt的ctime(創(chuàng)建時(shí)間)時(shí)間戳
os.path.exists(os.getcwd()) 判斷文件是否存在
os.path.expanduser('~/dir') 把~擴(kuò)展成用戶根目錄
os.path.expandvars('$PATH') 擴(kuò)展環(huán)境變量PATH
os.path.isfile(os.getcwd()) 判斷是否是文件名,1是0否
os.path.isdir('c:\Python26\temp') 判斷是否是目錄,1是0否
os.path.islink('/home/huaying/111.sql') 是否是符號(hào)連接 windows下不可用
os.path.ismout(os.getcwd()) 是否是文件系統(tǒng)安裝點(diǎn) windows下不可用
os.path.samefile(os.getcwd(), '/home/huaying') 看看兩個(gè)文件名是不是指的是同一個(gè)文件
os.path.walk('/home/huaying', test_fun, "a.c")
遍歷/home/huaying下所有子目錄包括本目錄,對(duì)于每個(gè)目錄都會(huì)調(diào)用函數(shù)test_fun.
例:在某個(gè)目錄中,和他所有的子目錄中查找名稱是a.c的文件或目錄。
def test_fun(filename, dirname, names): //filename即是walk中的a.c dirname是訪問的目錄名稱
if filename in names: //names是一個(gè)list,包含dirname目錄下的所有內(nèi)容
print os.path.join(dirname, filename)
os.path.walk('/home/huaying', test_fun, "a.c")
文件操作
打開文件
f = open("filename", "r") r只讀 w寫 rw讀寫 rb讀二進(jìn)制 wb寫二進(jìn)制 w+寫追加
讀寫文件
f.write("a") f.write(str) 寫一字符串 f.writeline() f.readlines() 與下read類同
f.read() 全讀出來 f.read(size) 表示從文件中讀取size個(gè)字符
f.readline() 讀一行,到文件結(jié)尾,返回空串. f.readlines() 讀取全部,返回一個(gè)list. list每個(gè)元素表示一行,包含"\n"\
f.tell() 返回當(dāng)前文件讀取位置
f.seek(off, where) 定位文件讀寫位置. off表示偏移量,正數(shù)向文件尾移動(dòng),負(fù)數(shù)表示向開頭移動(dòng)。
where為0表示從開始算起,1表示從當(dāng)前位置算,2表示從結(jié)尾算.
f.flush() 刷新緩存
關(guān)閉文件
f.close()
regular expression 正則表達(dá)式 import re
簡單的regexp
p = re.compile("abc") if p.match("abc") : print "match"
上例中首先生成一個(gè)pattern(模式),如果和某個(gè)字符串匹配,就返回一個(gè)match object
除某些特殊字符metacharacter元字符,大多數(shù)字符都和自身匹配。
這些特殊字符是 。^ $ * + ? { [ ] \ | ( )
字符集合(用[]表示)
列出字符,如[abc]表示匹配a或b或c,大多數(shù)metacharacter在[]中只表示和本身匹配。例:
a = ".^$*+?{\\|()" 大多數(shù)metachar在[]中都和本身匹配,但"^[]\"不同
p = re.compile("["+a+"]")
for i in a:
if p.match(i):
print "[%s] is match" %i
else:
print "[%s] is not match" %i
在[]中包含[]本身,表示"["或者"]"匹配.用
和
表示.
^出現(xiàn)在[]的開頭,表示取反.[^abc]表示除了a,b,c之外的所有字符。^沒有出現(xiàn)在開頭,即于身身匹配。
-可表示范圍.[a-zA-Z]匹配任何一個(gè)英文字母。[0-9]匹配任何數(shù)字。
\在[]中的妙用。
\d [0-9]
\D [^0-9]
\s [ \t\n\r\f\v]
\S [^ \t\n\r\f\v]
\w [a-zA-Z0-9_]
\W [^a-zA-Z0-9_]
\t 表示和tab匹配, 其他的都和字符串的表示法一致
\x20 表示和十六進(jìn)制ascii 0x20匹配
有了\,可以在[]中表示任何字符。注:單獨(dú)的一個(gè)"."如果沒有出現(xiàn)[]中,表示出了換行\(zhòng)n以外的匹配任何字符,類似[^\n].
regexp的重復(fù)
{m,n}表示出現(xiàn)m個(gè)以上(含m個(gè)),n個(gè)以下(含n個(gè)). 如ab{1,3}c和abc,abbc,abbbc匹配,不會(huì)與ac,abbbc匹配。
m是下界,n是上界。m省略表下界是0,n省略,表上界無限大。
*表示{,} +表示{1,} ?表示{0,1}
最大匹配和最小匹配 python都是最大匹配,如果要最小匹配,在*,+,?,{m,n}后面加一個(gè)?.
match object的end可以得到匹配的最后一個(gè)字符的位置。
re.compile("a*").match('aaaa').end() 4 最大匹配
re.compile("a*?").match('aaaa').end() 0 最小匹配
使用原始字符串
字符串表示方法中用\\表示字符\.大量使用影響可讀性。
解決方法:在字符串前面加一個(gè)r表示raw格式。
a = r"\a" print a 結(jié)果是\a
a = r"\"a" print a 結(jié)果是\"a
使用re模塊
先用re.compile得到一個(gè)RegexObject 表示一個(gè)regexp
后用pattern的match,search的方法,得到MatchObject
再用match object得到匹配的位置,匹配的字符串等信息
RegxObject常用函數(shù):
re.compile("a").match("abab") 如果abab的開頭和re.compile("a")匹配,得到MatchObject
_sre.SRE_Match object at 0x81d43c8
print re.compile("a").match("bbab")
None 注:從str的開頭開始匹配
re.compile("a").search("abab") 在abab中搜索第一個(gè)和re_obj匹配的部分
_sre.SRE_Match object at 0x81d43c8
print re.compile("a").search("bbab")
_sre.SRE_Match object at 0x8184e18 和match()不同,不必從開頭匹配
re_obj.findall(str) 返回str中搜索所有和re_obj匹配的部分.
返回一個(gè)tuple,其中元素是匹配的字符串.
MatchObject的常用函數(shù)
m.start() 返回起始位置,m.end()返回結(jié)束位置(不包含該位置的字符).
m.span() 返回一個(gè)tuple表示(m.start(), m.end())
m.pos(), m.endpos(), m.re(), m.string()
m.re().search(m.string(), m.pos(), m.endpos()) 會(huì)得到m本身
m.finditer()可以返回一個(gè)iterator,用來遍歷所有找到的MatchObject.
for m in re.compile("[ab]").finditer("tatbxaxb"):
print m.span()
高級(jí)regexp
| 表示聯(lián)合多個(gè)regexp. A B兩個(gè)regexp,A|B表示和A匹配或者跟B匹配.
^ 表示只匹配一行的開始行首,^只有在開頭才有此特殊意義。
$ 表示只匹配一行的結(jié)尾
\A 表示只匹配第一行字符串的開頭 ^匹配每一行的行首
\Z 表示只匹配行一行字符串的結(jié)尾 $匹配第一行的行尾
\b 只匹配詞的邊界 例:\binfo\b 只會(huì)匹配"info" 不會(huì)匹配information
\B 表示匹配非單詞邊界
示例如下:
print re.compile(r"\binfo\b").match("info ") #使用raw格式 \b表示單詞邊界
_sre.SRE_Match object at 0x817aa98
print re.compile("\binfo\b").match("info ") #沒有使用raw \b表示退格符號(hào)
None
print re.compile("\binfo\b").match("\binfo\b ")
_sre.SRE_Match object at 0x8174948
分組(Group) 示例:re.compile("(a(b)c)d").match("abcd").groups() ('abc', 'b')
#!/usr/local/bin/python
import re
x = """
name: Charles
Address: BUPT
name: Ann
Address: BUPT
"""
#p = re.compile(r"^name:(.*)\n^Address:(.*)\n", re.M)
p = re.compile(r"^name:(?P.*)\n^Address:(?P.*)\n", re.M)
for m in p.finditer(x):
print m.span()
print "here is your friends list"
print "%s, %s"%m.groups()
Compile Flag
用re.compile得到RegxObject時(shí),可以有一些flag用來調(diào)整RegxObject的詳細(xì)特征.
DOTALL, S 讓.匹配任意字符,包括換行符\n
IGNORECASE, I 忽略大小寫
LOCALES, L 讓\w \W \b \B和當(dāng)前的locale一致
MULTILINE, M 多行模式,只影響^和$(參見上例)
VERBOSE, X verbose模式
Python函數(shù)的參數(shù)類型主要包括必選參數(shù)、可選參數(shù)、可變參數(shù)、位置參數(shù)和關(guān)鍵字參數(shù),本文介紹一下他們的定義以及可變數(shù)據(jù)類型參數(shù)傳遞需要注意的地方。
必選參數(shù)(Required arguments)是必須輸入的參數(shù),比如下面的代碼,必須輸入2個(gè)參數(shù),否則就會(huì)報(bào)錯(cuò):
其實(shí)上面例子中的參數(shù) num1和num2也屬于關(guān)鍵字參數(shù),比如可以通過如下方式調(diào)用:
執(zhí)行結(jié)果:
可選參數(shù)(Optional arguments)可以不用傳入函數(shù),有一個(gè)默認(rèn)值,如果沒有傳入會(huì)使用默認(rèn)值,不會(huì)報(bào)錯(cuò)。
位置參數(shù)(positional arguments)根據(jù)其在函數(shù)定義中的位置調(diào)用,下面是pow()函數(shù)的幫助信息:
x,y,z三個(gè)參數(shù)的的順序是固定的,并且不能使用關(guān)鍵字:
輸出:
在上面的pow()函數(shù)幫助信息中可以看到位置參數(shù)后面加了一個(gè)反斜杠 / ,這是python內(nèi)置函數(shù)的語法定義,Python開發(fā)人員不能在python3.8版本之前的代碼中使用此語法。但python3.0到3.7版本可以使用如下方式定義位置參數(shù):
星號(hào)前面的參數(shù)為位置參數(shù)或者關(guān)鍵字參數(shù),星號(hào)后面是強(qiáng)制關(guān)鍵字參數(shù),具體介紹見強(qiáng)制關(guān)鍵字參數(shù)。
python3.8版本引入了強(qiáng)制位置參數(shù)(Positional-Only Parameters),也就是我們可以使用反斜杠 / 語法來定義位置參數(shù)了,可以寫成如下形式:
來看下面的例子:
python3.8運(yùn)行:
不能使用關(guān)鍵字參數(shù)形式賦值了。
可變參數(shù) (varargs argument) 就是傳入的參數(shù)個(gè)數(shù)是可變的,可以是0-n個(gè),使用星號(hào)( * )將輸入?yún)?shù)自動(dòng)組裝為一個(gè)元組(tuple):
執(zhí)行結(jié)果:
關(guān)鍵字參數(shù)(keyword argument)允許將任意個(gè)含參數(shù)名的參數(shù)導(dǎo)入到python函數(shù)中,使用雙星號(hào)( ** ),在函數(shù)內(nèi)部自動(dòng)組裝為一個(gè)字典。
執(zhí)行結(jié)果:
上面介紹的參數(shù)可以混合使用:
結(jié)果:
注意:由于傳入的參數(shù)個(gè)數(shù)不定,所以當(dāng)與普通參數(shù)一同使用時(shí),必須把帶星號(hào)的參數(shù)放在最后。
強(qiáng)制關(guān)鍵字參數(shù)(Keyword-Only Arguments)是python3引入的特性,可參考:。 使用一個(gè)星號(hào)隔開:
在位置參數(shù)一節(jié)介紹過星號(hào)前面的參數(shù)可以是位置參數(shù)和關(guān)鍵字參數(shù)。星號(hào)后面的參數(shù)都是強(qiáng)制關(guān)鍵字參數(shù),必須以指定參數(shù)名的方式傳參,如果強(qiáng)制關(guān)鍵字參數(shù)沒有設(shè)置默認(rèn)參數(shù),調(diào)用函數(shù)時(shí)必須傳參。
執(zhí)行結(jié)果:
也可以在可變參數(shù)后面命名關(guān)鍵字參數(shù),這樣就不需要星號(hào)分隔符了:
執(zhí)行結(jié)果:
在Python對(duì)象及內(nèi)存管理機(jī)制中介紹了python中的參數(shù)傳遞屬于對(duì)象的 引用傳遞 (pass by object reference),在編寫函數(shù)的時(shí)候需要特別注意。
先來看個(gè)例子:
執(zhí)行結(jié)果:
l1 和 l2指向相同的地址,由于列表可變,l1改變時(shí),l2也跟著變了。
接著看下面的例子:
結(jié)果:
l1沒有變化!為什么不是[1, 2, 3, 4]呢?
l = l + [4]表示創(chuàng)建一個(gè)“末尾加入元素 4“的新列表,并讓 l 指向這個(gè)新的對(duì)象,l1沒有進(jìn)行任何操作,因此 l1 的值不變。如果要改變l1的值,需要加一個(gè)返回值:
結(jié)果:
下面的代碼執(zhí)行結(jié)果又是什么呢?
執(zhí)行結(jié)果:
和第一個(gè)例子一樣,l1 和 l2指向相同的地址,所以會(huì)一起改變。這個(gè)問題怎么解決呢?
可以使用下面的方式:
也可以使用淺拷貝或者深度拷貝,具體使用方法可參考Python對(duì)象及內(nèi)存管理機(jī)制。這個(gè)問題在Python編程時(shí)需要特別注意。
本文主要介紹了python函數(shù)的幾種參數(shù)類型:必選參數(shù)、可選參數(shù)、可變參數(shù)、位置參數(shù)、強(qiáng)制位置參數(shù)、關(guān)鍵字參數(shù)、強(qiáng)制關(guān)鍵字參數(shù),注意他們不是完全獨(dú)立的,比如必選參數(shù)、可選參數(shù)也可以是關(guān)鍵字參數(shù),位置參數(shù)可以是必選參數(shù)或者可選參數(shù)。
另外,python中的參數(shù)傳遞屬于對(duì)象的 引用傳遞 ,在對(duì)可變數(shù)據(jù)類型進(jìn)行參數(shù)傳遞時(shí)需要特別注意,如有必要,使用python的拷貝方法。
參考文檔:
--THE END--