python - 函数
在許多編程語言中都存在函數(shù),python也不例外。
函數(shù)是將單一或者相關(guān)聯(lián)的功能打包的代碼段。函數(shù)將代碼打包,外界只需要調(diào)用接口,不必知道其實(shí)現(xiàn)過程
函數(shù)的意義是代碼復(fù)用,一次定義多次使用,不僅減輕了代碼工作者的作業(yè),而且使得程序的架構(gòu)更加完善,更改,維護(hù)得到提升,擴(kuò)展性更強(qiáng)(不用類的情況下)
python中的函數(shù)分為 內(nèi)置函數(shù) 和 用戶自定義函數(shù)。
內(nèi)置函數(shù)此處不講,下面我們看看用戶自定義函數(shù)
在python中,函數(shù)名的命名符合變量命名規(guī)則,一般就用駝峰式或用下劃線連接,如下:
1 >>> 2 >>> def MyFirstFunc(): #駝峰命名,這樣可以按照大小寫區(qū)分一個(gè)單詞,讀懂函數(shù)名的意思 3 pass 4 #這里定義的空函數(shù) 5 >>> 6 >>> def my_first_func(): #用'_'連接,個(gè)人覺得更清晰,所以一般自用這種方式命名函數(shù),用駝峰式命名類 7 pass 8 9 >>>python定義函數(shù)的固定格式:
? ? def function_name([arg1[,arg2...]]):
return
說明:
? ? ?def: 是 define function ,定義函數(shù)說明,python解釋器在讀到 def 時(shí),就會(huì)把其后的代碼塊當(dāng)成一個(gè)函數(shù),此時(shí)python解釋器不會(huì)把函數(shù)的代碼
讀到內(nèi)存中,跳過整個(gè)代碼塊繼續(xù)讀后面的代碼,當(dāng)函數(shù)被調(diào)用時(shí),python解釋器才會(huì)去解釋執(zhí)行函數(shù)的代碼塊。
? ? ?function_name: ?用戶自定義的函數(shù)名,注意不要與python里面存在的函數(shù)重名,否則相當(dāng)于重寫內(nèi)置函數(shù),若不需要,盡量避免。在定義完成后,
函數(shù)名就相當(dāng)于函數(shù)在內(nèi)存中地址的一個(gè)引用,此時(shí)若直接打印函數(shù)名,則會(huì)返回函數(shù)的內(nèi)存地址
? ? ?() :在定義時(shí)的固定格式,里面可以沒有參數(shù),也可以有參數(shù)(參數(shù)可以是python中各種數(shù)據(jù)結(jié)構(gòu))。在調(diào)用時(shí),函數(shù)名() 表示執(zhí)行函數(shù),所以經(jīng)常在
給函數(shù)名創(chuàng)建引用后,給引用加個(gè)()就能執(zhí)行函數(shù)
? ? ?[arg1[,arg2...]] : 表示可選參數(shù)
? ? ?' : ' ? :固定寫法,指明下面是屬于當(dāng)前行的代碼塊
? ? ?return : 函數(shù)中的出口。當(dāng)函數(shù)在執(zhí)行到return時(shí),當(dāng)前函數(shù)會(huì)結(jié)束執(zhí)行(后面的代碼將不會(huì)執(zhí)行),并把return后面的值(或表達(dá)式)返回,此時(shí)可以用
一個(gè)變量來接收函數(shù)的返回值,當(dāng)一個(gè)函數(shù)中沒有定義return時(shí),這個(gè)函數(shù)也有返回值,默認(rèn)返回None
1 >>> 2 >>> def hello(name): 3 print('hello %s' %name) 4 return 'hello everyone!' 5 print('just test') #沒有被執(zhí)行 6 7 8 >>> h = hello('root') # hello() 表示調(diào)用函數(shù) 9 hello root 10 >>>h11 'hello everyone!' 12 >>>
參數(shù)
? ? 在python中,參數(shù)是沒有類型的,類型是屬于對象。eg:
1 >>> 2 >>> l = [1,2,3,'a'] 3 >>> s = 'hello' 4 >>>? ? 上面的 [1,2,3,'a'] 是List類型,'hello' 是String類型,而變量 l、s 是沒有類型的,她僅僅是一個(gè)對象的引用(一個(gè)指針),可以是 List 類型對象,
也可以指向 String 類型對象。
?
在 python 中,strings, tuples, 和 numbers 是不可更改的對象,而 list,dict 等則是可以修改的對象。
-
不可變類型:變量賦值?a=5?后再賦值?a=10,這里實(shí)際是新生成一個(gè) int 值對象 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對象本身。比如在 fun(a)內(nèi)部修改 a 的值,只是修改另一個(gè)復(fù)制的對象,不會(huì)影響 a 本身。
-
可變類型:類似 c++ 的引用傳遞,如 列表,字典。如 fun(la),則是將 la 真正的傳過去,修改后fun外部的la也會(huì)受影響
對上面?zhèn)鬟f不可變對象,eg:
1 >>> 2 >>> def test(a): 3 a = 10 # a 是一個(gè)局部變量,只是作用在函數(shù)test內(nèi)部,出了函數(shù),是不能調(diào)用它的 4 5 6 >>> b = 2 7 >>> test(b) #因?yàn)閎=2,是numbers,不可變類型,所以這里傳遞的是值2,即test(2),所以函數(shù)里面的更改與 b 無關(guān) 8 >>> b 9 2 10 >>> a 11 Traceback (most recent call last): 12 File "<pyshell#40>", line 1, in <module> 13 a 14 NameError: name 'a' is not defined 15 >>>對上面可變類型,eg:
1 >>> l = [1, 2, 3, 4, 5] 2 >>> def change_list(ol): 3 if len(ol) >= 3: 4 ol[2] = 'hello' 5 return 'just test' 6 else: 7 print('Not change everything') 8 9 10 >>> cl = change_list(l) 11 >>> l 12 [1, 2, 'hello', 4, 5] 13 >>> cl 14 'just test' 15 >>>python 中一切都是對象,嚴(yán)格意義我們不能說 值傳遞 還是 引用傳遞,我們應(yīng)該說傳 不可變對象 和傳 可變對象 。
傳遞給函數(shù)的參數(shù)也有很多種形式:
? ? 關(guān)鍵字參數(shù): 實(shí)參位置與形參位置按順序一一對應(yīng)
1 >>> 2 >>> def say_hello(name1,name2): 3 print('name1:',name1) 4 print('name2:',name2) 5 return 'just test' 6 7 >>> sh = say_hello('admin','root') 8 name1: admin 9 name2: root 10 >>> sh = say_hello('root','admin') 11 name1: root 12 name2: admin 13 >>>? ? 指定參數(shù): 類似鍵值對,對傳遞參數(shù)的位置順序無關(guān)
1 >>> 2 >>> def say_hello(name1,name2): 3 print('name1:',name1) 4 print('name2:',name2) 5 return 'just test' 6 7 >>> sh = say_hello(name2='admin',name1='root') 8 name1: root 9 name2: admin 10 >>>? ? 默認(rèn)參數(shù): 在函數(shù)定義時(shí)為參數(shù)賦初值,防止后面沒輸入報(bào)錯(cuò) (注意:有默認(rèn)值的參數(shù)放在最后)
1 >>> 2 >>> def user_info(name,age,hobbie='python'): 3 print('%s is %s year old and his hobbie is %s' %(name,age,hobbie)) 4 5 >>> ui = user_info('root',22,'php') 6 root is 22 year old and his hobbie is php 7 >>> ui = user_info('root',22) 8 root is 22 year old and his hobbie is python 9 >>> type(ui) 10 <class 'NoneType'> 11 >>>? ?動(dòng)態(tài)參數(shù):參數(shù)可變,自動(dòng)把傳入的參數(shù)轉(zhuǎn)換為元祖或字典
? ? ? ? 前面有一個(gè)*,如 *args 表示 會(huì)把接受到的 非鍵值對形式 的所有參數(shù)放進(jìn)一個(gè)元祖里面
前面有兩個(gè)*,如 **kwargs 表示 會(huì)把接收到的 鍵值對形式 的所有參數(shù)放進(jìn)一個(gè)字典里面
? ? 注意:鍵值對形式的參數(shù)必須放在最后面?
1 >>> 2 >>> def collect_func(*args,**kwargs): 3 print('your input *args:',args) # * 只是指明后面的參數(shù)是(元祖)收集參數(shù),并不是變量名的一部分,同理,** 也是(字典)收集參數(shù) 4 print('your input **kwargs:',kwargs) 5 6 7 >>> collect_func(1,2,'hello',[5,6],'a',name='root',age=22) 8 your input *args: (1, 2, 'hello', [5, 6], 'a') 9 your input **kwargs: {'name': 'root', 'age': 22} 10 11 >>> collect_func(1,2,'hello',age=22,[5,6],'a',name='root') 12 SyntaxError: positional argument follows keyword argument 13 >>>變量作用域:
? ? ? ? 在函數(shù)內(nèi)部定義的變量為局部變量,僅在函數(shù)內(nèi)有用,出了函數(shù)就無法訪問。全局變量易于訪問,但不易于修改。
? ? ? ? 若要在函數(shù)內(nèi)部定義一個(gè)全局變量,可用 global ?eg: 在函數(shù)內(nèi): ?global x = 10 ?(global會(huì)影響執(zhí)行速度,并且不安全,不建議這樣用)
? ? 注意:
在函數(shù)內(nèi)部修改全局變量(如重新賦值),python會(huì)自動(dòng)新建一個(gè)與全局變量名字相同的局部變量。全局變量存在于棧中,局部變量
? ? ? ? 存在于其他地方,所以互不影響
閉包:
? ? ? 閉包使用實(shí)例:裝飾器
? ? ? 注意:
? ? ? ? 使用函數(shù)時(shí):在函數(shù)內(nèi)部和程序其他部分可以使用的變量不同,在函數(shù)內(nèi)應(yīng)該只是使用通過參數(shù)傳遞進(jìn)來的變量,而在函數(shù)外部,應(yīng)該只使用接收函數(shù)返回值的變量
1 >>> 2 >>> def func1(): 3 print('func1正在被調(diào)用...') 4 def func2(): 5 print('func2正在被調(diào)用...') 6 return func2 7 8 >>> a = func1() 9 func1正在被調(diào)用... 10 >>> a() 11 func2正在被調(diào)用... 12 >>> func2() #不能直接從外部調(diào)用某個(gè)函數(shù)的內(nèi)嵌函數(shù) ,內(nèi)嵌函數(shù)的作用域都在外部函數(shù)內(nèi) 13 Traceback (most recent call last): 14 File "<pyshell#57>", line 1, in <module> 15 func2() 16 NameError: name 'func2' is not defined 17 >>>匿名函數(shù):
? ? lambda 表達(dá)式
? ? 作用:
1、在使用函數(shù)時(shí),用lambda表達(dá)式可以省下定義函數(shù)的過程
? 2、簡化代碼可讀性
1 >>> 2 >>> g = lambda x,y:x+y 3 >>> g(3,5) 4 8 5 >>>? ? ? ? 說明:lambda后面空格,然后跟變量,有多個(gè)變量用 ' , ' 隔開,' : '是參數(shù)和函數(shù)體的分割點(diǎn),' : '后面表示是函數(shù)體,
? ? 給lambda 表達(dá)式創(chuàng)建引用(一個(gè)指針) g ,使g指向lambda表達(dá)式的地址,再加上 () 執(zhí)行l(wèi)ambda 表達(dá)式
過濾器:
作用:篩選,把滿足條件的去掉,留下的生成一個(gè)filter object,可用list將其轉(zhuǎn)化
1 >>> 2 >>> #用法:filter(function or None , iterable) 3 >>> 4 >>> l = [1,0,3,'a',False,True] 5 >>> filter(None,l) 6 <filter object at 0x0000014EC44EBBA8> 7 >>> list(filter(None,l)) 8 [1, 3, 'a', True] 9 >>> 10 >>> #用filter寫一個(gè)篩選奇數(shù)的函數(shù) 11 >>> 12 >>> def singnal_num(x): #這里用lambda改進(jìn): lambda x:x%2 13 return x%2 14 15 >>> ls = range(10) 16 >>> show = filter(singnal_num,ls) #show = filter(lambda x:x%2,ls) 17 >>> list(show) 18 [1, 3, 5, 7, 9] 19 >>>映射:map()
將序列的每一個(gè)元素作為函數(shù)的參數(shù)(對應(yīng)除默認(rèn)參數(shù)外,只能傳遞一個(gè))進(jìn)行運(yùn)算加工,直到把序列的所有元素加工完畢,返回所有加工后的元素構(gòu)成的新序列
1 >>> 2 >>> #用法: map(規(guī)則函數(shù),迭代器) 3 >>> 4 >>> m = map(lambda x:x*2,range(10)) 5 >>> list(m) 6 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 7 >>> 8 >>> [i for i in m] 9 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] 10 >>>?
轉(zhuǎn)載于:https://www.cnblogs.com/xtsec/p/6678340.html
總結(jié)
以上是生活随笔為你收集整理的python - 函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++命名(自定义)
- 下一篇: 循序渐进学Python2变量与输入