三、函式

並不傻的狍子發表於2020-12-20

一、建立一個函式

關鍵字def,函式名後面必須加()括號

>>> def MyFirstFunction():
	print('這是我建立的第一個函式')

>>> MyFirstFunction()
這是我建立的第一個函式

Python中函式的使用規範和C/C++沒有太大區別。也是先宣告後使用。

函式的返回值,直接在函式中用return就可以

二、形參和實參

類C/C++

三、說明文件

每一個函式都應該有良好的註釋習慣。寫好說明文件是必備的,可以用內建的函式的__doc__屬性檢視說明文件。如下:

def MyFirstFunction(name):
    '函式定義過程中的name是叫形參'
    #因為他只是一個形式,表示佔據一個引數位置
    print("傳遞進來的" + name + "叫做實參,因為他是具體的引數值")

MyFirstFunction("小明")
print(MyFirstFunction.__doc__)

程式碼中帶引號括起來的地方就是說明文件,#號後面的是註釋文件,不會儲存在__doc__屬性中。

用help(MyFirstFunction)也可以檢視說明文件

四、關鍵字引數

關鍵字引數是為了防止多個引數時,順序難以記憶容易出錯的問題。

>>> def SaySome(name,words):
	    print(name+'->'+words)

>>> SaySome('小甲魚','讓程式設計改變世界!')
小甲魚->讓程式設計改變世界!
>>> SaySome('讓程式設計改變世界!','小甲魚')
讓程式設計改變世界!->小甲魚
>>> SaySome(words='讓程式設計改變世界!',name='小甲魚')
小甲魚->讓程式設計改變世界!

可以用引數名=引數的樣子來指定。

五、預設引數

>>> def SaySome(name='小甲魚',words='讓程式設計改變世界!'):
	    print(name+'->'+words)

>>> SaySome()
小甲魚->讓程式設計改變世界!
>>> SaySome('小明')
小明->讓程式設計改變世界!

當函式存在預設引數時,如果使用者不指定引數將使用預設引數。

六、收集引數(可變引數)

用*來表示引數,如def test(*params),這樣不指定引數的個數。可以由任意個引數。實際是將引數打包,傳入了一個元組。效果如下:

>>> def test(*params):
	print('引數的長度是:',len(params))
	print('第二個引數是:',params[1])

>>> test(1,'a',2.1,[1,2,3])
引數的長度是: 4
第二個引數是: a

如果除了收集引數,還有一個引數 def test(*params,name),則使用第二個引數時一定要指定引數,否則會預設都賦給收集引數。

七、函式與過程

函式是有返回值的,過程不會返回任何值。即使是空函式也會返回一個None。只是不顯現。

Python可以用列表返回多個值。也可以直接用逗號隔開,返回一個元組。

八、函式變數的作用域

區域性變數和全域性變數。在函式內部直接更改全域性變數的話是無法實現的,函式內部會產生一個和全域性變數一樣名稱的變數覆蓋全域性變數,全域性變數並沒有修改。但是全域性變數在函式中也是可以正常使用的,但不能直接更改。

在函式內部用global宣告一下全域性變數,就可以更改全域性變數的值

九、內嵌函式

允許在一個函式內部建立另一個函式。

>>> def fun1():
	print('fun1()正在被呼叫...')
	    def fun2():
		    print('fun2()正在被呼叫...')
	fun2()

>>> fun1()
fun1()正在被呼叫...
fun2()正在被呼叫...

fun2函式的所有定義都是在fun1中定義的,只能在fun1中呼叫,不能在外部呼叫。

十、閉包

如果在一個內部函式裡,對外部作用域(但不是在全域性作用域的)的變數進行引用,那麼內部函式就會被認為是閉包。如下:

>>> def FunX(x):
	    def FunY(y):
		    return x*y
	return FunY

>>> i=FunX(8)
>>> i
<function FunX.<locals>.FunY at 0x000001715C59CD30>
>>> type(i)
<class 'function'>
>>> i(5)
40

FunY是內部函式,他使用了外部函式FunX的變數。所以FunY就是閉包的。在程式中i得到的是FunX返回的函式FunY等同於FunY。

也可以直接用FunX(8)(5)呼叫,直接返回40

注意,在內部函式中使用外部函式的變數要注意,如下,更改時會報錯(引用沒問題,不能更改),類似於全域性變數和區域性變數

def Fun1():
	x=5
	def Fun2():
		x*=x
		return x
	return Fun2()
print(Fun1())

為了解決問題可以使用列表型別或者在內部函式中使用nonlocal關鍵字宣告x

十一、匿名函式

lambda關鍵字建立匿名函式。

>>> lambda x:2*x+1
<function <lambda> at 0x00000224907B30D0>
>>> g=lambda x:2*x+1
>>> g(5)
11

在程式中,冒號前是變數,冒號後是函式表示式。函式是沒有名字的,所以叫做匿名函式,所以給函式起一個名字g,用g(5)便可呼叫函式。

lambda表示式的作用:

Python寫一些執行指令碼時,使用lambda就可以省下定義函式過程,比如說我們只是需要寫個簡單的指令碼來管理伺服器時間,我們就不需要專門定義一個函式然後再寫呼叫,使用lambda就可以使得程式碼更加精簡。

對於一些比較抽象並且整個程式執行下來只需要呼叫一兩次的函式,有時候給函式起個名字也是比較頭疼的問題,使用lambda就不需要考慮命名的問題了。

簡化程式碼的可讀性,由於普通的函式閱讀經常要跳到開頭def定義部分,使用lambda函式可以省去這樣的步驟。

十二、兩個內建函式filter和map

(一)filter()過濾器

filter會篩選出值為True的資料。filter的第一個引數為函式,第二個引數為序列,會將序列中的每一個引數代入函式中,保留下返回值為True的值組成新的列表,如下:

>>> filter(None,[1,0,False,True])
<filter object at 0x00000224907A7910>
>>> list(filter(None,[1,0,False,True]))
[1, True]

可以結合lambda寫出簡潔的程式碼:

>>> def odd(x):
	return x%2

>>> temp=range(10)
>>> show=filter(odd,temp)
>>> list(show)
[1, 3, 5, 7, 9]
>>> list(filter(lambda x:x%2,range(10)))
[1, 3, 5, 7, 9]

(二)map()對映

map的引數也是第一個為函式,第二個為可迭代列表。將序列的每一個元素作為函式的引數進行運算加工直到可迭代的序列每個元素都加工完畢,返回一個新的序列。

>>> list(map(lambda x:x*2,range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> list(map(lambda x,y:x*2+y,range(10),range(10)))
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

 

相關文章