這篇筆記記錄的知識(shí)點(diǎn):
- 函數(shù)的基本概念
- 自定義函數(shù)
- 函數(shù)的幾種參數(shù)
編程的三種方式:
1.OOP 面向?qū)ο缶幊蹋f物皆對(duì)象熊楼,以class為主,抽象化
2.POP 面向過程編程,萬事皆過程驼侠,def定義過程
3.函數(shù)式編程,將某種功能封裝起來谆吴,用的時(shí)候直接調(diào)用函數(shù)名倒源,def定義函數(shù),也叫function/方法/過程/子程序
</br>
函數(shù)的基礎(chǔ)概念:
- 函數(shù)是一種設(shè)計(jì)工具,它能讓程序員將復(fù)雜的系統(tǒng)分解成可管理的部件, 用于將相關(guān)功能打包并參數(shù)化
- 一組語句的集合通過一個(gè)名字(函數(shù)名)封裝起來句狼,要想執(zhí)行這個(gè)函數(shù)笋熬,只需要調(diào)用其函數(shù)名即可
- 可以理解為是一個(gè)帶有名字的,具有一定功能的,用于完成具體工作的代碼塊.
- 當(dāng)程序需要多次執(zhí)行同一個(gè)任務(wù)時(shí),只需要調(diào)用具有該功能的函數(shù)即可.
- 函數(shù)特性:
- 代碼重用
- 保持一致性
- 可擴(kuò)展性
-
Python的函數(shù)可以分為兩類:
-
內(nèi)置函數(shù):
python內(nèi)置了一系列的常用函數(shù),以便于使用. 我們可以根據(jù)不同的功能需求直接調(diào)用使用.
自定義函數(shù):
我們自己根據(jù)功能需求,以固定的語句格式定義的函數(shù).空函數(shù)
pass語句什么都不做.
實(shí)際上pass是用來作為占位符腻菇,比如現(xiàn)在還沒想好怎么寫函數(shù)的代碼胳螟,就可以先放一個(gè)pass,讓代碼能運(yùn)行起來筹吐。def func1(): pass
-
- 常見的幾種函數(shù):
- 全局函數(shù) (定義在模塊中,僅限單個(gè)文件)
- 局部函數(shù)(嵌套于其他函數(shù)中)
- lambda函數(shù)(匿名函數(shù))
- 內(nèi)置函數(shù)
</br>
自定義函數(shù)
定義函數(shù)的格式:
python定義函數(shù)使用def關(guān)鍵字糖耸,一般格式如下:
def 函數(shù)名(參數(shù)):
'''文檔字串符(docstring),注釋,描述該函數(shù)是做什么的'''
函數(shù)體(代碼行) #這個(gè)函數(shù)要實(shí)現(xiàn)的功能代碼
函數(shù)名的命名規(guī)則:
- 函數(shù)名必須以下劃線或字母開頭,可以包含任意字母丘薛、數(shù)字或下劃線的組合嘉竟。不能使用任何的標(biāo)點(diǎn)符號(hào);
- 函數(shù)名是區(qū)分大小寫的。
- 函數(shù)名不能是保留字(關(guān)鍵字)
函數(shù)的調(diào)用
定義了函數(shù)之后周拐,就相當(dāng)于有了一個(gè)具有某些功能的代碼
但是,函數(shù)是不會(huì)自動(dòng)執(zhí)行的,想要讓這些代碼能夠執(zhí)行铡俐,需要調(diào)用它
調(diào)用函數(shù)很簡(jiǎn)單的,通過 函數(shù)名()
即可完成調(diào)用:
def test1(): # 定義函數(shù)名
print("hello!") # 定義函數(shù)的功能
test1() # 調(diào)用函數(shù)
函數(shù)的文檔說明
文檔字串符(docstring)描述該函數(shù)是做什么的,盡量給自定義函數(shù)備注,方便日后查看使用.
def test(a,b):
'''用來完成對(duì)2個(gè)數(shù)求和'''
print("%d" % (a+b))
test(11,22)
如果執(zhí)行妥粟,以下代碼:
help(test)
能夠看到test函數(shù)的相關(guān)說明:
Help on function test in module __main__:
test(a, b)
用來完成對(duì)2個(gè)數(shù)求和
(END)
Tips: 使用三引號(hào)來構(gòu)成文檔字符串审丘,用來解釋該函數(shù)的主要功能,這是一個(gè)很好的編碼習(xí)慣.
</br>
函數(shù)的參數(shù)
實(shí)參和形參
實(shí)參是一個(gè)實(shí)實(shí)在在存在的參數(shù)勾给,是實(shí)際占用內(nèi)存地址的
形參只是意義上的一種參數(shù)滩报,在定義的時(shí)候是不占內(nèi)存地址的.
- 定義時(shí)小括號(hào)中的參數(shù),用來接收參數(shù)用的播急,稱為 “形參”
- 調(diào)用時(shí)小括號(hào)中的參數(shù)脓钾,用來傳遞給函數(shù)用的,稱為 “實(shí)參”
形參:形式參數(shù)桩警,不是實(shí)際存在可训,是虛擬變量,在定義函數(shù)和函數(shù)體的時(shí)候使用形參捶枢,目的就是在函數(shù)調(diào)用的時(shí)候接收實(shí)參(實(shí)參個(gè)數(shù)握截,類型應(yīng)與實(shí)參一一對(duì)應(yīng))
實(shí)參:實(shí)際參數(shù),調(diào)用函數(shù)時(shí)候傳給函數(shù)的變量烂叔,可以是常量谨胞,變量,表達(dá)式蒜鸡,函數(shù)胯努,傳給形參
區(qū)別:形參是虛擬的,不占用內(nèi)存空間逢防,形參變量只有在調(diào)用時(shí)才分配內(nèi)存單元叶沛,實(shí)參是一個(gè)變量,占用空間忘朝,數(shù)據(jù)傳送單向灰署,實(shí)參傳給形參,不能形參傳給實(shí)參辜伟。
def sum_num(a,b): #a,b 是形參
sum_num = a+b
print(sum_num)
sum_num(10,33) #10,33 是實(shí)參
定義時(shí)小括號(hào)中的參數(shù)氓侧,用來接收參數(shù)用的脊另,稱為 “形參”
調(diào)用時(shí)小括號(hào)中的參數(shù)导狡,用來傳遞給函數(shù)用的,稱為 “實(shí)參”
沒特別指明偎痛,形參和實(shí)參必須一一對(duì)應(yīng)旱捧,多一個(gè)少一個(gè)都報(bào)錯(cuò)
</br>
常用的幾種參數(shù)類型:
在Python中可以使用必選參數(shù),默認(rèn)參數(shù),可變參數(shù)枚赡,關(guān)鍵字參數(shù)氓癌,這四類可以一起使用,或者只使用其中某一些.
但是有多種參數(shù),在定義函數(shù)和傳參的時(shí)候,必須要注意參數(shù)的置放順序:
參數(shù)的順序必須是:
<h6 align = "center" >必備參數(shù)贫橙,可變(不定長(zhǎng))參數(shù)*args
, 默認(rèn)(缺省)參數(shù)贪婉,可變(不定長(zhǎng))參數(shù)**kargs
,關(guān)鍵字參數(shù) </h6>
1. 必備參數(shù)(位置參數(shù))
- 調(diào)用函數(shù)時(shí)根據(jù)函數(shù)定義的參數(shù)位置來傳遞參數(shù)卢肃。
- 所有參數(shù)的順序必須一一對(duì)應(yīng)疲迂,且少一個(gè)參數(shù)都不可以
def func_1(name,sex):
sex_dict = {1: u'先生', 2: u'女士'}
print ('hello %s %s, welcome to python world!' %(name, sex_dict.get(sex, u'先生')))
func_1("劉",2)
運(yùn)行結(jié)果:hello 劉 女士, welcome to python world!
2. 默認(rèn)參數(shù)(缺省參數(shù))
- 在形參中默認(rèn)有值的參數(shù)
- python為了簡(jiǎn)化函數(shù)的調(diào)用,提供了默認(rèn)參數(shù)機(jī)制
- 用于定義函數(shù)莫湘,為參數(shù)提供默認(rèn)值尤蒿,調(diào)用函數(shù)時(shí)可傳可不傳該默認(rèn)參數(shù)的值(注意:所有位置參數(shù)必須出現(xiàn)在默認(rèn)參數(shù)前,包括函數(shù)定義和調(diào)用)
- 在定義有默認(rèn)參數(shù)的函數(shù)時(shí)幅垮,需要注意以下:
- 必選參數(shù)必須在前面腰池,默認(rèn)參數(shù)在后;
- 設(shè)置何種參數(shù)為默認(rèn)參數(shù)忙芒?一般來說示弓,將參數(shù)值變化小的設(shè)置為默認(rèn)參數(shù)。
def func_2(name,age=18):
print("我是位置參數(shù):%s"%name,"我是默認(rèn)參數(shù):%s"%age)
func_2("如花") #只給name傳參,會(huì)調(diào)用默認(rèn)參數(shù)的值
func_2("如花",28) #給age傳參,會(huì)覆蓋之前的默認(rèn)參數(shù)
運(yùn)行結(jié)果如下:
我是位置參數(shù):如花 我是默認(rèn)參數(shù):18
我是位置參數(shù):如花 我是默認(rèn)參數(shù):28
3. 可變參數(shù)(不定長(zhǎng)參數(shù))
- 也叫做不定長(zhǎng)參數(shù),動(dòng)態(tài)參數(shù)
- 定義函數(shù)時(shí)匕争,有時(shí)候我們不確定調(diào)用的時(shí)候會(huì)傳遞多少個(gè)參數(shù)(不傳參也可以)避乏。此時(shí),可用包裹(packing)位置參數(shù)
*args
甘桑,或者包裹關(guān)鍵字參數(shù)**kargs
拍皮,來進(jìn)行參數(shù)傳遞,會(huì)顯得非常方便跑杭。 - 有時(shí)可能需要一個(gè)函數(shù)能處理比當(dāng)初聲明時(shí)更多的參數(shù), 這些可變參數(shù)也被叫做不定長(zhǎng)參數(shù)铆帽,聲明時(shí)不會(huì)命名。
- 加了星號(hào)(*)的變量args會(huì)存放所有未命名的變量參數(shù)德谅,args為元組
- 而加**的變量kwargs會(huì)存放命名參數(shù)爹橱,即形如key=value的參數(shù), kwargs為字典
(1) 包裹位置傳遞*args
我們傳進(jìn)的所有參數(shù)都會(huì)被args變量收集窄做,它會(huì)根據(jù)傳進(jìn)參數(shù)的位置合并為一個(gè)元組(tuple)愧驱,args是元組類型,這就是包裹位置傳遞椭盏。
def func(*args):
....
# func()
# func(a)
# func(a, b, c)
(2)包裹關(guān)鍵字傳遞**kargs
kargs是一個(gè)字典(dict)组砚,收集所有關(guān)鍵字參數(shù)
def func(**kargs):
....
# func(a=1)
# func(a=1, b=2, c=3)
(3) 對(duì)于*args
和**kwargs
在函數(shù)中我們可以稱之為參數(shù)組,但是這兩個(gè)還是有區(qū)別的
1:args的功能:------接收N個(gè)位置參數(shù)掏颊,轉(zhuǎn)換成元組tuple形式
2:kwargs的功能------接收N個(gè)關(guān)鍵字參數(shù)糟红,轉(zhuǎn)換成字典dict形式
3:位置參數(shù)一定要在關(guān)鍵字參數(shù)之前艾帐,也就是(args,**kwargs)
(4) *args
和**kwargs
一起用, 功能會(huì)更強(qiáng)大
可以兩個(gè)一起使用:功能更加的強(qiáng)大:會(huì)把無參數(shù)名臣的封裝成一個(gè)tuple 把有參數(shù)名稱的封裝成一個(gè)字典盆偿;并且柒爸,arg必須在**kwargs前面
# def show(*args ,**kwargs):
# print(args,kwargs)
# show(11,22,33,nn=22,kk=33)
值得注意的是雖然*args
和**kwargs
會(huì)把我們給他的參數(shù)封裝成列表和字典,但是如果我們?cè)诮o定實(shí)際參數(shù)的時(shí)候給的是一個(gè)列表或者是字典事扭,只是表示只有一個(gè)實(shí)參捎稚,而不是列表和字典里面的值;如果想要實(shí)現(xiàn)這個(gè)功能求橄,那么我們就需要在列表或者字典前面加上*
或者**
就能實(shí)現(xiàn)了阳藻;
4. 關(guān)鍵字參數(shù)
用于函數(shù)調(diào)用,通過“鍵-值”形式加以指定谈撒⌒饶啵可以讓函數(shù)更加清晰、容易使用啃匿,同時(shí)也清除了參數(shù)的順序需求蛔外。
#以下是用關(guān)鍵字參數(shù)正確調(diào)用函數(shù)的實(shí)例
func_01('tanggu', sex=1)
func_01(1, name='tanggu')
func_01(name='tanggu', sex=1)
func_01(sex=1, name='tanggu')
# 以下是錯(cuò)誤的調(diào)用方式
func_01(name='tanggu', 1)
func_01(sex=1, 'tanggu')
tips:雖然函數(shù)參數(shù)類型很多,但不要同時(shí)使用太多的組合溯乒,否則函數(shù)接口的可理解性很差.
</br>
函數(shù)的返回值
函數(shù)的返回值是函數(shù)重要的組成部分夹厌。函數(shù)的根本在于實(shí)現(xiàn)程序的部分功能,所以很多時(shí)候我們需要將函數(shù)執(zhí)行后的結(jié)果返回給程序再由程序作出進(jìn)一步的操作裆悄∶疲可以說是函數(shù)的返回值令函數(shù)與函數(shù)之間,函數(shù)與主程序之間更加緊密的聯(lián)系起來光稼。
函數(shù)的返回值:
- 在Python的函數(shù)中都有一個(gè)返回值或南,默認(rèn)為None。也可以使用return value語句來定義一個(gè)且只能定義一個(gè)可為任意類型的返回值艾君。但是我們能夠返回一個(gè)序列類型的對(duì)象采够,來實(shí)現(xiàn)返回多個(gè)值的效果。
- 函數(shù)外部的代碼要想獲取函數(shù)的執(zhí)行結(jié)果冰垄,就可以在函數(shù)里面用return語句蹬癌,把結(jié)果返回.
- return 代表一個(gè)函數(shù)的終止,函數(shù)在執(zhí)行過程中只要遇到return語句虹茶,就會(huì)停止執(zhí)行逝薪,并返回結(jié)果.如果return 后面帶一個(gè)print 或者return ,則后面的不執(zhí)行
- 如果未在函數(shù)中指定return蝴罪,那么這個(gè)函數(shù)的返回值就是None
def func_2(name,age=18):
print("我是位置參數(shù):%s"%name,"我是默認(rèn)參數(shù):%s"%age)
func_2("如花") #只給name傳參
func_2("如花",28) #給age傳參,會(huì)覆蓋之前的默認(rèn)參數(shù)
def without_return(a,b): #定義一個(gè)沒有return的函數(shù)
print(a+b)
print(a-b)
def with_return(a,b): #定義一個(gè)有return的函數(shù)
return a+b
return a-b
result1 = without_return(5,10) #調(diào)用上邊定義的沒有return的函數(shù)
result2 = with_return(5,10) #調(diào)運(yùn)上邊定義的有return的函數(shù)
print("沒有返回值的函數(shù):",result1)
print("有返回值的函數(shù):",result2)
上段代碼運(yùn)行后,結(jié)果如下:
15
-5
沒有返回值的函數(shù): None
有返回值的函數(shù): 15
[注意:]
- 定義的函數(shù)沒有返回值,調(diào)用時(shí)接用變量收到的是None
- 函數(shù)體里的代碼執(zhí)行完后會(huì)回到函數(shù)調(diào)用的地
- 函數(shù)體里有多個(gè)return語法不會(huì)報(bào)錯(cuò),但是不能做到返回多個(gè)值的操作
- 函數(shù)執(zhí)行到return語句表示函數(shù)執(zhí)行結(jié)束,后邊有再多也不會(huì)執(zhí)行了
接收多個(gè)rerun值
理論上,return只能返回一個(gè)值; 如果想要返回多個(gè)值,可以考慮把多個(gè)值放在列表,元祖,字典里邊.
def return_value():
print('返回多個(gè)值')
return [1,3,5]
#return (1,3,5)
#return {'a':1,'b':2,'c':3}
result = return_value()
print(result)
上述代碼運(yùn)行結(jié)果:
返回多個(gè)值
[1, 3, 5]
- return后面可以是元組董济,列表、字典等洲炊,只要是能夠存儲(chǔ)多個(gè)數(shù)據(jù)的類型感局,就可以一次性返回多個(gè)數(shù)據(jù)
- 如果return后面有多個(gè)數(shù)據(jù),那么默認(rèn)是元組
函數(shù)的嵌套調(diào)用
- 函數(shù)的嵌套,在函數(shù)里邊再定義一個(gè)函數(shù)
- 調(diào)用可以理解為,是在一個(gè)函數(shù)里調(diào)用了其他函數(shù)
- 嵌套函數(shù)不能在外部使用,只能在函數(shù)內(nèi)部使用
def show_msg():
print("show_msg")# 在函數(shù)里面定義的函數(shù)就是嵌套函數(shù)
def show():
print("我是函數(shù)體里面的內(nèi)部函數(shù)->>子函數(shù)")
show() # 在函數(shù)體里面調(diào)用嵌套函數(shù)
show_msg() # 調(diào)用函數(shù)
# 注意點(diǎn): 嵌套函數(shù)不能再函數(shù)外使用暂衡,只能在函數(shù)內(nèi)部使用
上述代碼運(yùn)行結(jié)果:
show_msg
我是函數(shù)體里面的內(nèi)部函數(shù)->>子函數(shù)
函數(shù)嵌套的小應(yīng)用: 使用冰箱:
- 在實(shí)際開發(fā)中,使用函數(shù)的嵌套可以大大的提高代碼的可讀性
def use_ice_box(eat):
# 嵌套函數(shù)的作用询微,把函數(shù)拆分成不同的功能函數(shù)
# 打開冰箱
def open_ice_box():
print("打開冰箱門")
# 向冰箱放入食物
def put_eat(eat):
print("把%s放入冰箱" % eat)
# 關(guān)閉冰箱
def close_ice_box():
print("關(guān)閉冰箱門")
open_ice_box()
put_eat(eat)
close_ice_box()
use_ice_box("蘋果")
局部變量和全局變量,函數(shù)的作用域
變量作用域
LEGB原則
- Python中,程序的變量并不是在哪個(gè)位置都可以訪問的狂巢,訪問權(quán)限決定于這個(gè)變量是在哪里賦值的撑毛。
- 變量的作用域決定了在哪一部分程序可以訪問哪個(gè)特定的變量名稱。
- Python的作用域一共有4種唧领,如下:
- L ( Local):函數(shù)內(nèi)的區(qū)域藻雌,包括局部變量和形參。
- E(Enclosing):外面嵌套函數(shù)區(qū)域斩个,常見的是閉包函數(shù)外的函數(shù)胯杭。
- G( Global):全局作用域。
- B( Built-in): 內(nèi)建作用域受啥。
- Python中變量是采用L -> E->G一>B的規(guī)則查找
- 當(dāng)Python檢索變量的時(shí)候做个,先是在局部中查找,如果找不到滚局,便會(huì)去局部外的局部找(例如閉包)居暖,再找不到就會(huì)去全局找,再者去內(nèi)中找藤肢。
局部變量
- 局部變量太闺,就是在函數(shù)內(nèi)部定義的變量
- 作用范圍:只能在函數(shù)體里面使用
- 局部變量的作用: 臨時(shí)存儲(chǔ)函數(shù)體里面的所需要的數(shù)據(jù)的
- 局部變量等函數(shù)執(zhí)行完成以后會(huì)釋放
- 如果函數(shù)里面return了一個(gè)返回值,那么等外界使用完成以后該返回值以后才會(huì)釋放
全局變量和關(guān)鍵字global
- 如果一個(gè)變量嘁圈,既能在一個(gè)函數(shù)中使用省骂,也能在其他的函數(shù)中使用,這樣的變量就是全局變量
- 也可以理解成在函數(shù)外定義的變量就是全局變量
num1 = 1 #<--全局變量
def funcA():
num1 = 3 #<--- 局部變量.可以理解為定義了一個(gè)局部變量最住,只不過局部變量的名字和全局變量的名字相同而已冀宴,不是同一個(gè)變量
print("funcA里的變量:",num1)
def funcB():
print("funcB里的變量:",num1)
funcA()
funcB()
上述代碼運(yùn)行結(jié)果:
funcA里的變量: 3
funcB里的變量: 1
使用關(guān)鍵字global
修改全局變量
當(dāng)內(nèi)部作用域想修改外部作用域的變量時(shí),要用到global和nonlocal關(guān)鍵字了温学。
global關(guān)鍵字用來在函數(shù)或其他局部作用域中使用全局變量略贮。但是如果不修改全局變量也可以不使用global關(guān)鍵字。
- 如果在函數(shù)中出現(xiàn)
global 全局變量名字
, 那么這個(gè)函數(shù)中即使出現(xiàn)和全局變量名相同的變量名 = 數(shù)據(jù)
也理解為對(duì)全局變量進(jìn)行修改仗岖,而不是定義局部變量 - global 表示聲明要修改全局變量
- 如果在一個(gè)函數(shù)中需要對(duì)多個(gè)全局變量進(jìn)行修改逃延,那么可以使
global a, b,...n
- 也可以多次用global聲明,
global a
,global b
# 修改全局變
num1 = 1
def funcA():
global num1 # <-- 表示聲明要修改全局變量
num1 = 3
print("funcA里的變量:",num1)
def funcB():
print("funcB里的變量:",num1)
funcA()
funcB()
運(yùn)行結(jié)果:
funcA里的變量: 3
funcB里的變量: 3
在Python中,以上邊代碼為例,如果在函數(shù)內(nèi)部對(duì)全局變量num1
進(jìn)行修改轧拄, Python會(huì)把變量num1
當(dāng)做是局部變量揽祥,為了使全局變量生效,我們可以在函數(shù)內(nèi)使用global關(guān)鍵字進(jìn)行聲明
.
如果沒有對(duì)變量num1
進(jìn)行全局變量申明檩电,運(yùn)行程序后會(huì)報(bào)錯(cuò):UnboundLocalError: local variable 'a' referenced before assignment
nonlocal關(guān)鍵字
nonlocal
是在Python3.0中新增的關(guān)鍵字拄丰,python2.x不提供支持府树。
使用nonlocal關(guān)鍵字
可以在一個(gè)嵌套的函數(shù)中修改嵌套作用域中的變量。
示例一:
def FinalResult():
result = 0
print("外部函數(shù)的變量result的值為:"+ str(result))
def sumResult():
result = 12
print("內(nèi)部函數(shù)的變量result的值為"+str(result))
sumResult()
FinalResult()
上述示例一代碼運(yùn)行結(jié)果如下:
外部函數(shù)的變量result的值為:0
內(nèi)部函數(shù)的變量result的值為12
示例二:
def FinalResult():
result = 0
#print("外部函數(shù)的變量result的值為:"+ str(result))
def sumResult():
result = 12
print("內(nèi)部函數(shù)的變量result的值為"+str(result))
sumResult()
print("外部函數(shù)的變量result的值為:"+ str(result))
FinalResult()
上述示例二代碼運(yùn)行結(jié)果如下:
內(nèi)部函數(shù)的變量result的值為12
外部函數(shù)的變量result的值為:0
注意 通過上述示例可以看出, 嵌套在函數(shù)FinalResult
內(nèi)部的內(nèi)嵌函數(shù)sumResult
中, 我們對(duì)變量result的賦值,其實(shí)本質(zhì)是重新創(chuàng)建了一個(gè)新的變量,而不是外部函數(shù)FinalResult
中result=0
這條語句的重新賦值.
(2) 通過調(diào)換外部函數(shù)的print語句
和調(diào)用內(nèi)部函數(shù)sumResult
兩條語句的先后位置, 可以對(duì)比發(fā)現(xiàn), 內(nèi)部函數(shù)的變量賦值,無論什么時(shí)候被調(diào)用都沒有對(duì)外部的同名變量造成影響.
示例三:
- 使用
nonlocal關(guān)鍵字
- 在內(nèi)部嵌套的函數(shù)
sumResult
中使用了nonlocal關(guān)鍵字料按,就會(huì)告訴Python在外部的函數(shù)FinalResult
中使用嵌套作用域中的變量result
- 這樣,當(dāng)我們?cè)趦?nèi)嵌函數(shù)中對(duì)變量
result
進(jìn)行修改時(shí)奄侠,會(huì)直接影響到整個(gè)嵌套作用域中的result變量
def FinalResult():
result = 0
def sumResult():
nonlocal result
result = 12
print("內(nèi)部函數(shù)的變量result的值為"+str(result))
sumResult()
print("外部函數(shù)的變量result的值為:"+ str(result))
FinalResult()
上述示例三代碼運(yùn)行結(jié)果如下:
內(nèi)部函數(shù)的變量result的值為12
外部函數(shù)的變量result的值為:12
- 使用
global
關(guān)鍵字修飾的變量之前可以不存在 - 使用
nonlocal
關(guān)鍵字修飾的變量之前不存在,運(yùn)行會(huì)報(bào)錯(cuò):SyntaxError: no binding for nonlocal 'result' found
[小總結(jié):]
一個(gè)變量在函數(shù)體外,一個(gè)變量在函數(shù)體內(nèi), 改變量用global
.
一個(gè)變量在內(nèi)嵌函數(shù)里,一個(gè)變量在包裹內(nèi)嵌函數(shù)的外層函數(shù)里,改變量nonlocal
多層嵌套函數(shù)和函數(shù)外同用一個(gè)變量,用global申明.
(這段代碼為實(shí)驗(yàn),不確定全適用,也有可能方法有點(diǎn)蠢,因?yàn)楹髞戆l(fā)現(xiàn),貌似可以用return( ̄. ̄))
- 申明變量的原則是,哪里用就在哪里申明.
假設(shè)我們有一個(gè)變量result
,這個(gè)變量會(huì)在函數(shù)體外使用,也會(huì)在多層嵌套的函數(shù)的某幾個(gè)層里使用.
我們希望達(dá)到的效果是:在任何一個(gè)地方修改變量result
,所有位置的變量result
的值都改變,即在之后無論在函數(shù)外還是函數(shù)內(nèi)再調(diào)用這個(gè)變量result
,得到的是最新的result
的值.具體實(shí)現(xiàn)如下:
示例四:
result = 10 # <== 函數(shù)外的變量result
print("函數(shù)外的result變量:"+str(result)) #<== 第一條print執(zhí)行語句
def FinalResult():
global result <== 申明result為全局變量, 這里如果不申明, 知result程序默認(rèn)不是同一個(gè)變量,只是同名.
result = 11
print("外部函數(shù)的變量result的值為:"+ str(result)) # <== 第2條print執(zhí)行語句
def sumResult():
#nonlocal resul # <== 這里如果用nonlocal,會(huì)報(bào)錯(cuò)
global result #用global申明result為全局變量
result = 12
print("內(nèi)部函數(shù)的變量result的值為"+str(result)) # <== 第3條print執(zhí)行語句
sumResult()
print("調(diào)用完最里層函數(shù)后,再次打印外部函數(shù)的變量result的值為:"+ str(result)) #<== 第四條print執(zhí)行語句
FinalResult()
print("調(diào)用完最里層函數(shù)后,再次打印函數(shù)外的result變量:",result) #<== 第5條print執(zhí)行語句
[小總結(jié):]
- 我的目的是在最里層的函數(shù)sumResult里修改變量
result
為12,之后再調(diào)用它的外層函數(shù)中的變量result
或再次調(diào)用整個(gè)函數(shù)體外的變量result
時(shí), 這個(gè)result
的值都是12 - 需要兩次global申明, 遵循'申明變量的原則是,哪里用就在哪里申明'
- 如果只在內(nèi)層函數(shù)中g(shù)lobal申明,但外層函數(shù)中的
result
不申明, 再次調(diào)用,函數(shù)體外邊的這個(gè)result變?yōu)?2了,外層函數(shù)中的result的值依舊是11.
- 如果只在內(nèi)層函數(shù)中g(shù)lobal申明,但外層函數(shù)中的
</br>
函數(shù)的拆包 & 交換變量值
- 拆包:把容器中的每一個(gè)數(shù)據(jù)拆分到不同變量進(jìn)行保存數(shù)據(jù)
- 容器:列表,字典载矿, 元組垄潮, 字符串
- 拆包時(shí)要注意,需要拆的數(shù)據(jù)的個(gè)數(shù)要與變量的個(gè)數(shù)相同闷盔,一一對(duì)應(yīng)弯洗,不能多,否則程序會(huì)異常
拆包
list1 = [2,3,4]
a,b,c =list1 # 拆包的時(shí)候需要一一對(duì)應(yīng),不能多
print(a, b)
tuple1 = ("張三", "李四")
name1, name2 = tuple1
print(name1, name2)
dict1 = {"name": "小新", "age": 5}.values()
value1, value2 = dict1
print(value1, value2)
str1 = "apple"
a, b, c, d, e, = str1
print(a, b, c,d,e)
上述代碼運(yùn)行結(jié)果:
2 3
張三 李四
小新 5
a p p l e
[注意:]變量名的數(shù)量一定要和容器內(nèi)元素的數(shù)量一模一樣,否則會(huì)報(bào)錯(cuò).
例: alueError: not enough values to unpack (expected 6, got 5)
,ValueError: too many values to unpack (expected 4)
交換兩個(gè)變量的值
- 一般用法:
- 通用的交換變量的方式:定義臨時(shí)變量
num1 = 1
num2 = 2
num3 = num1
num1 = num2
num2 = num3
print(num1, num2)
- Python特有的用法
num1 = 1
num2 = 2
num1, num2 = num2, num1
print(num1, num2)
多函數(shù)程序的基本使用流程
一般在實(shí)際開發(fā)過程中逢勾,一個(gè)程序往往由多個(gè)函數(shù))組成牡整,并且多個(gè)函數(shù)共享某些數(shù)據(jù),這種場(chǎng)景是經(jīng)常出現(xiàn)的溺拱,因此下面來總結(jié)下果正,多個(gè)函數(shù)中共享數(shù)據(jù)的幾種方式:
- 使用全局變量
- 使用函數(shù)的返回值、參數(shù)
- 函數(shù)嵌套調(diào)用
- 使用全局變量
- 多個(gè)函數(shù)可以使用同一個(gè)全局變量
- 全局變量可以在函數(shù)里共享數(shù)據(jù)
score = 100
# 修改全局變量數(shù)據(jù)的函數(shù)
def modify():
# 聲明修改全局變量
global score
# 修改全局變量
score = 90
print("modify:", score)
# 獲取全局變量修改后的數(shù)據(jù)
def show():
# 獲取全局變量的數(shù)據(jù)
print("獲取全局變量修最新的數(shù)據(jù):", score)
modify()
show()
上述代碼運(yùn)行后的結(jié)果:
modify: 90
獲取全局變量修最新的數(shù)據(jù): 90
- 使用函數(shù)的返回值盟迟、參數(shù)
- 函數(shù)的返回值可以作為其他函數(shù)的參數(shù)
def return_value():
return "哈哈"
def show_info(msg):
print(msg)
# 1.獲取函數(shù)的返回值
value = return_value()
# 2.把函數(shù)的返回值作為其他函數(shù)的參數(shù)使用
show_info(value)
上述代碼的運(yùn)行結(jié)果:
哈哈
- 函數(shù)嵌套調(diào)用
def test1():
# 通過return將一個(gè)數(shù)據(jù)結(jié)果返回
return 20
def test2():
# 1. 先調(diào)用test1并且把結(jié)果返回來
result = test1()
# 2. 對(duì)result進(jìn)行處理
print(result)
# 調(diào)用test2時(shí)秋泳,完成所有的處理
test2()
上述代碼運(yùn)行結(jié)果:
20
總結(jié):函數(shù)使用注意事項(xiàng)
1. 自定義函數(shù)
-
函數(shù)名不能重復(fù)
- 如果在同一個(gè)程序中出現(xiàn)了多個(gè)相同函數(shù)名的函數(shù),那么在調(diào)用函數(shù)時(shí)就會(huì)出現(xiàn)問題攒菠,所以要避免名字相同
- 還有一點(diǎn) 不僅要避免函數(shù)名之間不能相同迫皱,還要避免 變量名和函數(shù)名相同的,否則都會(huì)出現(xiàn)問題
一個(gè)函數(shù)到底有沒有返回值辖众,就看有沒有return卓起,因?yàn)橹挥衦eturn才可以返回?cái)?shù)據(jù)
在開發(fā)中往往根據(jù)需求來設(shè)計(jì)函數(shù)需不需要返回值
函數(shù)中,可以有多個(gè)return語句凹炸,但是只要執(zhí)行到一個(gè)return語句戏阅,那么就意味著這個(gè)函數(shù)的調(diào)用完成
在調(diào)用函數(shù)時(shí),如果需要把一些數(shù)據(jù)一起傳遞過去啤它,被調(diào)用函數(shù)就需要用參數(shù)來接收
參數(shù)列表中變量的個(gè)數(shù)根據(jù)實(shí)際傳遞的數(shù)據(jù)的多少來確定
無參數(shù)奕筐、無返回值
def 函數(shù)名():
語句
無參數(shù)、有返回值
def 函數(shù)名():
語句
return 需要返回的數(shù)值
有參數(shù)变骡、無返回值
def 函數(shù)名(形參列表):
語句
有參數(shù)离赫、有返回值
def 函數(shù)名(形參列表):
語句
return 需要返回的數(shù)值
2.調(diào)用函數(shù)
調(diào)用的方式為:函數(shù)名([實(shí)參列表])
- 如果調(diào)用的函數(shù) 在定義時(shí)有形參,那么在調(diào)用的時(shí)候就應(yīng)該傳遞參數(shù)
- 調(diào)用時(shí)塌碌,實(shí)參的個(gè)數(shù)和先后順序應(yīng)該和定義函數(shù)中要求的一致
- 如果調(diào)用的函數(shù)有返回值渊胸,那么就可以用一個(gè)變量來進(jìn)行保存這個(gè)值
3.作用域
- 在一個(gè)函數(shù)中定義的變量,只能在本函數(shù)中用(局部變量)
- 在函數(shù)外定義的變量台妆,可以在所有的函數(shù)中使用(全局變量)
參考資料:
- 傳智博客講義
- 廖雪峰老師的教程
- cnblog-python的位置參數(shù)翎猛、默認(rèn)參數(shù)胖翰、關(guān)鍵字參數(shù)、可變參數(shù)區(qū)別
- cnblog-python 函數(shù)參數(shù)類型
- 戰(zhàn)爭(zhēng)熱誠的博客
擴(kuò)展閱讀:
cnblog-Python進(jìn)階-函數(shù)默認(rèn)參數(shù)