摘要:缺省參數(shù)就是給參數(shù)設(shè)定默認(rèn)值,如果在傳參過程中,缺省參數(shù)傳入值的話則依照傳入的值,如果沒有傳入值則按照默認(rèn)的值。
python基礎(chǔ)3
1、函數(shù)基本語法及特性
2、函數(shù)參數(shù)
3、局部變量和全局變量
4、返回值
嵌套函數(shù)
5、遞歸函數(shù)
6、匿名函數(shù)
7、高階函數(shù)
8、內(nèi)置函數(shù)
9、函數(shù)式編程
在編程語言中的函數(shù)并非數(shù)學(xué)意義上的函數(shù)(總是返回根據(jù)參數(shù)計(jì)算得到的結(jié)果),編程語言中的函數(shù)也稱為過程,在使用這個(gè)函數(shù)的時(shí)候有可能不會(huì)返回一個(gè)結(jié)果或者說返回的結(jié)果不是數(shù)學(xué)意義上的函數(shù)執(zhí)行的結(jié)果。
一、函數(shù)基本語法及特性 1、抽象和結(jié)構(gòu)抽象是程序能夠被別人理解的關(guān)鍵所在(無論對(duì)編寫程序還是閱讀程序來說,這都至關(guān)重要)。
程序應(yīng)非常抽象,如下載網(wǎng)頁、計(jì)算使用頻率、打印每個(gè)單詞的使用頻率。下面將上述簡(jiǎn)單描述轉(zhuǎn)換為一個(gè)Python程序:
page = download_page() freqs = compute_frequencies(page) for word, freq in freqs: print(word, freq)
看到這些代碼,任何人都知道這個(gè)程序是做什么的。至于具體該如何做那么我們就得在函數(shù)中得出定義。
在比如打印斐波那契數(shù)(一種數(shù)列,其中每個(gè)數(shù)都是前兩個(gè)數(shù)的和)
fibs = [0,1] for i in range(8): fibs.append(fibs[-2] + fibs[-1]) print(fibs)
上述代碼會(huì)打印出斐波那契數(shù)的前十個(gè),當(dāng)然你也可以指定要打印數(shù)的個(gè)數(shù):
num = int(input("How many Fibonacci numbers do you want?")) fib = [0,1] for i in range(num-2): fibs.append(fibs[-2] + fibs[-1]) print(fibs)
當(dāng)我們?cè)谄渌胤较胧褂眠@些數(shù)的時(shí)候,你可能會(huì)想到我再把這個(gè)循環(huán)再寫一次,對(duì)于這段代碼是可以的,但是對(duì)于更加復(fù)雜的代碼你還愿意去重寫嗎?真正的程序員會(huì)去抽象程序,把一些想要實(shí)現(xiàn)的功能抽象為函數(shù),直接調(diào)用這個(gè)函數(shù)來實(shí)現(xiàn)指定的功能,讓程序更加簡(jiǎn)潔、易懂并且降低代碼的重復(fù)率。真正的程序員會(huì)像下面這樣做:
num = int(input("How many Fibonacci numbers do you want?")) print(fibs(num))2、函數(shù)的定義
def 函數(shù)名(): 函數(shù)體
例如:
def hello(): print("Hello world!")3、給函數(shù)編寫文檔
要給函數(shù)編寫文檔,以確保其他人能夠理解,可添加注釋。放在函數(shù)開頭的字符串成為文檔字符串(docstring),將作為函數(shù)的一部分存儲(chǔ)起來。例如:
def square(x): "Calculates the square of the number x." return x * x
可以像下面這樣訪問文檔字符串:
>>> square.__doc__ "Calculates the square of the number x."
特殊的內(nèi)置函數(shù)help很有用。在交互式解釋器中,可使用它獲取有關(guān)函數(shù)的信息,其中包含函數(shù)的文檔字符串。
>>> help(square) Help on function square in module __main__: square(x) Calculates the square of the number x.
為了讓一個(gè)函數(shù)更通用,在定義函數(shù)的時(shí)候可以讓函數(shù)接收數(shù)據(jù),函數(shù)接收的數(shù)據(jù)就是函數(shù)的參數(shù)。
1、參數(shù)的基本應(yīng)用 (1)定義帶參數(shù)的函數(shù)示例如下:
def add(a,b): c = a + b print(c)(2)調(diào)用帶參數(shù)的函數(shù)
以上面的add函數(shù)為例,我們調(diào)用該函數(shù),代碼如下:
def add(a,b): c = a + b print(c) add(11,22) #調(diào)用帶參數(shù)的函數(shù)時(shí),需要在小括號(hào)中傳遞數(shù)據(jù)(3)調(diào)用函數(shù)時(shí)參數(shù)的順序
>>> def test(a,b): ... print(a,b) ... >>> test(1,2) 1 2 >>> test(b=1,a=2) 2 1 >>> >>> test(b=1,2) File "", line 1 SyntaxError: positional argument follows keyword argument >>> >>>
通過以上代碼我們可以看出,函數(shù)的參數(shù)在調(diào)用的過程中是一一對(duì)應(yīng)的,如果不指定那個(gè)實(shí)參是那個(gè)對(duì)應(yīng)的形參時(shí),會(huì)默認(rèn)按實(shí)參的順序?qū)?shí)參賦值給形參。
(4)總結(jié)定義時(shí)小括號(hào)中的參數(shù),用來接收參數(shù)用的,稱為“形參”
調(diào)用時(shí)小括號(hào)中的參數(shù),用來傳遞給函數(shù)的,稱為“實(shí)參”
2、參數(shù)的高級(jí)應(yīng)用 (1)缺省參數(shù)調(diào)用函數(shù)時(shí),缺省參數(shù)的值如果沒有傳入,則被認(rèn)為是默認(rèn)值。缺省參數(shù)就是給參數(shù)設(shè)定默認(rèn)值,如果在傳參過程中,缺省參數(shù)傳入值的話則依照傳入的值,如果沒有傳入值則按照默認(rèn)的值。如下代碼:
def sum(a,b=11): result = a + b print("%d+%d=%d"%(a,b,result)) sum(11,22) #調(diào)用函數(shù)時(shí)會(huì)將11和22分別賦值給a和b sum(10,) #調(diào)用函數(shù)時(shí),由于只給了一個(gè)實(shí)參,則10賦值給a,b則用默認(rèn)的參數(shù)值11
程序運(yùn)行結(jié)果如下:
注意:帶有默認(rèn)值的參數(shù)一定要位于參數(shù)列表的最后面。
>>> def printinfo(name, age=35, sex): ... print name ... File "(2)不定長(zhǎng)參數(shù)", line 1 SyntaxError: non-default argument follows default argument
有時(shí)可能需要一個(gè)函數(shù)能處理比當(dāng)初聲明時(shí)更多的參數(shù),這些參數(shù)叫做不定長(zhǎng)參數(shù),聲明時(shí)不會(huì)命名。
基本語法如下:
def functionname([formal_args,] *args, **kwargs): "函數(shù)_文檔字符串" function_suite return [expression]
加*號(hào)的變量args會(huì)存放所有未命名的變量參數(shù),args為元組 加**號(hào)的變量kwargs會(huì)存放命名參數(shù),即形如key=value的參數(shù),kwargs為字典
可變參數(shù)示例:
>>> def fun(a, b, *args, **kwargs): ... """可變參數(shù)演示示例""" ... print "a =", a ... print "b =", b ... print "args =", args ... print "kwargs: " ... for key, value in kwargs.items(): ... print key, "=", value ... >>> fun(1, 2, 3, 4, 5, m=6, n=7, p=8) # 注意傳遞的參數(shù)對(duì)應(yīng) a = 1 b = 2 args = (3, 4, 5) kwargs: p = 8 m = 6 n = 7 >>> >>> >>> c = (3, 4, 5) >>> d = {"m":6, "n":7, "p":8} >>> fun(1, 2, *c, **d) # 注意元組與字典的傳參方式 a = 1 b = 2 args = (3, 4, 5) kwargs: p = 8 m = 6 n = 7 >>> >>> >>> fun(1, 2, c, d) # 注意不加星號(hào)與上面的區(qū)別 a = 1 b = 2 args = ((3, 4, 5), {"p": 8, "m": 6, "n": 7}) kwargs: >>> >>>(3)引用傳參
可變類型與不可變類型的變量分別作為函數(shù)參數(shù)時(shí),會(huì)有什么不同?
Python有沒有類似C語言中的指針傳參?
>>> def selfAdd(a): ... """自增""" ... a += a ... >>> a_int = 1 >>> a_int 1 >>> selfAdd(a_int) >>> a_int 1 >>> a_list = [1, 2] >>> a_list [1, 2] >>> selfAdd(a_list) >>> a_list [1, 2, 1, 2]
Python中函數(shù)參數(shù)是引用傳遞(注意不是值傳遞)。對(duì)于不可變類型,因變量不能修改,所以運(yùn)算不會(huì)影響到變量自身;而對(duì)于可變類型來說,函數(shù)體中的運(yùn)算可能會(huì)更改傳入的參數(shù)變量。
如下代碼示例:
>>> def selfAdd(a): ... """自增""" ... a = a + a # 我們更改了函數(shù)體的這句話 ... >>> a_int = 1 >>> a_int 1 >>> selfAdd(a_int) >>> a_int 1 >>> a_list = [1, 2] >>> a_list [1, 2] >>> selfAdd(a_list) >>> a_list [1, 2] # 想一想為什么沒有變呢?
Python中變量之間的賦值利用到引用,只要是有"="就是引用,引用就是變量中存儲(chǔ)的是地址,而地址指向的內(nèi)存空間是存真實(shí)數(shù)據(jù)地方。a = a + a會(huì)創(chuàng)建一個(gè)新的內(nèi)存空間,然后讓變量a指向這段空間;而a += a是將a所指向的那段空間的值變?yōu)閍 + a。如下demo:
>>> a = [1,2] >>> id(a) 31329224 >>> a = a + a >>> a [1, 2, 1, 2] >>> id(a) 31991944 >>> b = 2 >>> id(b) 1587990368 >>> b = b + b >>> b 4 >>> id(b) 1587990432 >>> c = [1,2] >>> id(c) 31992072 >>> c += c >>> c [1, 2, 1, 2] >>> id(c) 31992072 >>>
局部變量,就是定義在函數(shù)內(nèi)部的變量,其作用單位只是在函數(shù)體內(nèi);
不同的函數(shù),可以定義相同名字的局部變量,其不會(huì)產(chǎn)生影響;
局部變量的作用:為了臨時(shí)保存數(shù)據(jù)需要在函數(shù)中定義變量來進(jìn)行存儲(chǔ)。
示例:
def test1(): a = 100 #此時(shí)的a為局部變量,作用范圍只在test1函數(shù)內(nèi) def test2(): print("a=%d"%a) test1() test2()
此時(shí)由于a是局部變量,其做作用范圍只在test1函數(shù)中,相當(dāng)于test2函數(shù)中沒有定義變量a,所以上述程序在運(yùn)行時(shí)會(huì)報(bào)如下錯(cuò)誤:
2、全局變量 (1)什么是全局變量如果一個(gè)變量既能在函數(shù)體中使用,也能在其他函數(shù)中使用,這樣的變量稱為全局變量。
示例:
#定義全局變量 a = 100 def test1(): print("a=%d"%a) def test2(): print("a=%d"%a) #調(diào)用函數(shù) test1() test2()
由于變量a是全局變量,所以在test1和test2兩個(gè)函數(shù)中都可以使用變量a,運(yùn)行結(jié)果如下:
(2)全局變量與局部變量同名的問題當(dāng)全局變量與局部變量同名時(shí),在定義該局部變量的函數(shù)體內(nèi)以局部變量為主,如下示例:
#定義全局變量 a = 100 def test1(): a = 300 print("---test1--修改前--a=%d"%a) a = 200 print("---test1--修改后--a=%d"%a) def test2(): print("---test2---a=%d"%a) test1() test2()
此時(shí),對(duì)于test1函數(shù),函數(shù)體內(nèi)定義了和全部變量同名的局部變量a,此時(shí)會(huì)以函數(shù)中的變量a為根據(jù);對(duì)于test2函數(shù),函數(shù)體內(nèi)沒有定義和全局變量同名的局部變量,所以如果test2函數(shù)使用變量a,則以全部變量a為根據(jù)。運(yùn)行結(jié)果如下:
(3)修改全局變量既然是全局變量,就可以在所有的函數(shù)中是,那么是否可以修改呢?看如下代碼:
#定義全局變量 a = 100 def test1(): global a print("---test1--修改前--a=%d"%a) a = 200 print("---test1--修改后--a=%d"%a) def test2(): print("---test2---a=%d"%a) test1() test2()
代碼運(yùn)行結(jié)果如下:
在函數(shù)體內(nèi)利用global這個(gè)關(guān)鍵字來聲明變量為全局變量,此時(shí)在函數(shù)體內(nèi)對(duì)該變量的操作就是相當(dāng)于對(duì)全局變量的操作。
(4)可變類型的全局變量看下面兩個(gè)代碼示例的區(qū)別:
#定義全局變量 a = 100 def test1(): print("---test1--修改前--a=%d"%a) a = 200 print("---test1--修改后--a=%d"%a) def test2(): print("---test2---a=%d"%a) test1() test2()
上述代碼運(yùn)行結(jié)果為:
#定義全局變量 a = [11,22,33] def test1(): print("---test1--修改前--",a) a.append(44) print("---test1--修改前--",a) def test2(): print("---test2--修改前--",a) test1() test2()
上述代碼運(yùn)行結(jié)果為:
對(duì)于上述兩種情況,列表(list)、字典(dict)這種可變的類型的全局變量不用再函數(shù)體內(nèi)聲明全局變量,在函數(shù)體中對(duì)該變量的操作就是在對(duì)全局變量進(jìn)行操作;而像數(shù)值類型(int,flaot,bool,long)、字符串(str)、元組(tuple)這種不可變類型的操作,要想在函數(shù)體內(nèi)對(duì)這種全局變量進(jìn)行操作,必須在函數(shù)體內(nèi)聲明其為全局變量。
(5)總結(jié)在函數(shù)外邊定義的變量叫全局變量
全局變量能夠在所有的函數(shù)中進(jìn)行訪問
如果在函數(shù)中修改全局變量,那么就需要使用global進(jìn)行聲明
如果全局變量的名字和局部變量的名字相同,那么使用的是局部變量的,小技巧強(qiáng)龍不壓地頭蛇
在函數(shù)中不使用global聲明全局變量時(shí)不能修改全局變量的本質(zhì)是不能修改全局變量的指向,即不能將全局變量指向新的數(shù)據(jù)
對(duì)于不可變類型的全局變量來說,因其指向的數(shù)據(jù)不能修改,所以不能使用global時(shí)無法修改全局變量
對(duì)于可變類型的全局變量來說,因其指向的數(shù)據(jù)可以修改,所以不使用global時(shí)也可修改全局變量
“返回值”,就是程序中函數(shù)完成一件事情后,最后給調(diào)用者返回的結(jié)果。
1、帶有返回值的函數(shù)想要在函數(shù)中把結(jié)果返回給調(diào)用者,需要在函數(shù)中使用return
如下示例:
def add2num(a, b): c = a+b return c 或者 def add2num(a, b): return a + b2、保存函數(shù)的返回值
在程序中,如果一個(gè)函數(shù)返回了一個(gè)數(shù)據(jù),那么想要用這個(gè)數(shù)據(jù),就需要用一個(gè)變量來保存函數(shù)返回的數(shù)據(jù)。示例如下:
#定義函數(shù) def add2num(a, b): return a+b #調(diào)用函數(shù),順便保存函數(shù)的返回值 result = add2num(100,98) #因?yàn)閞esult已經(jīng)保存了add2num的返回值,所以接下來就可以使用了 print result
3、Python返回多值
看如下代碼:
def test(a,b): sum2 = a + b mulit = a * b return [sum2,mulit] result = test(2,3) print(result)
運(yùn)行結(jié)果為:
[5,6]
def test(a,b): sum2 = a + b mulit = a * b return sum2,mulit result = test(2,3) print(result)
運(yùn)行結(jié)果為:
(5,6)
由上述示例我們可以得出,當(dāng)有多個(gè)返回值時(shí),利用列表將結(jié)果返回,那么函數(shù)就會(huì)返回一個(gè)列表;當(dāng)將幾個(gè)返回值用逗號(hào)隔開返回時(shí),默認(rèn)返回的是元組。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/44943.html
摘要:嘗射于家圃,有賣油翁釋擔(dān)而立,睨之,久而不去??得C問曰汝亦知射乎吾射不亦精乎翁曰無他,但手熟爾??得C忿然曰爾安敢輕吾射翁曰以我酌油知之。 開啟變身模式 大家好, 從這一期開始,我們會(huì)從小白變身為中等小白,在基礎(chǔ)起步階段有太多的東西我沒有講到,但是俗話說的好,無他,但手熟爾,只要多多練習(xí),時(shí)間會(huì)是最好的證明,相信我們終有一天會(huì)成為高手,因此從這一系列開始,讓我們一起更上一層樓,還是和往常...
前情回顧 大家好,我又回來了。今天我會(huì)繼續(xù)和大家分享itertools這個(gè)神奇的自帶庫,首先,讓我們回顧一下上一期結(jié)尾的時(shí)候我們講到的3個(gè)方法: combinations() combinations_with_replacement() permutations() 讓我們對(duì)這3個(gè)在排列組合中經(jīng)常會(huì)使用到的函數(shù)做個(gè)總結(jié) combinations() 基礎(chǔ)概念 模板:combinations...
前言 最近,我在群里答疑的時(shí)候,經(jīng)常碰到,小伙伴,再變量,縮進(jìn),參數(shù),方面使用錯(cuò)誤,導(dǎo)致程序運(yùn)行不來。 今天,打算自己寫一篇。 Python 變量作用域,和生命周期。 徹底弄懂變量該怎么使用。 知識(shí)點(diǎn) 變量的使用,有作用域區(qū)別,也有生命周期的區(qū)別。 1.變量作用域 局部變量 python能夠影響變量作用域的代碼段是def、class、lamda。 def scopeTest(): local...
摘要:另外,這些中的每一個(gè)都是純函數(shù),有返回值。例如,如果要計(jì)算整數(shù)列表的累積乘,或者求和等等基礎(chǔ)語法參數(shù)是連續(xù)作用于每一個(gè)元素的方法,新的參數(shù)為上一次執(zhí)行的結(jié)果,為被過濾的可迭代序列返回值最終的返回結(jié)果在中,是一個(gè)內(nèi)置函數(shù)。 簡(jiǎn)潔的內(nèi)置函數(shù) 大家好,我又回來了,今天我想和大家分享的是Python非常重要的幾個(gè)內(nèi)置函數(shù):map,filter,reduce, zip。它們都是處理序列的便捷函數(shù)...
閱讀 3623·2021-09-06 15:13
閱讀 1600·2021-09-02 10:19
閱讀 2545·2019-08-30 15:52
閱讀 980·2019-08-29 15:25
閱讀 1642·2019-08-26 18:36
閱讀 575·2019-08-26 13:23
閱讀 1406·2019-08-26 10:46
閱讀 3568·2019-08-26 10:41