我們目前為止,已經(jīng)可以完成一些軟件的基本功能了,現(xiàn)在我們自己來實(shí)現(xiàn)一個(gè)len,但是不能使用len
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、成都網(wǎng)站建設(shè)、云州網(wǎng)絡(luò)推廣、微信平臺(tái)小程序開發(fā)、云州網(wǎng)絡(luò)營銷、云州企業(yè)策劃、云州品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供云州建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:aaarwkj.com
a = "sadsfsfg"
count = 0
for i in a:
count += 1
print(count)
我們現(xiàn)在實(shí)現(xiàn)了一個(gè)求長度,我還想讓你們求一下列表和元組的長度 是不是就要將我們寫的內(nèi)容再次拿過來
我們在求一個(gè)字典的長度,也需要將我們寫好的內(nèi)容拿過來使用 好像程序中好多都是一樣的,所以可以將它封裝起來,多次重復(fù)使用
def 是python中關(guān)鍵字主要用來定義函數(shù)的
len這個(gè)是函數(shù)的名字
()這個(gè)括號(hào)是個(gè)神奇的東西,用來定義參數(shù)
: 冒號(hào)是表示咱們這個(gè)語句寫完了
函數(shù)體就是有4個(gè)空格的縮進(jìn)
def len():
a = "sadassb"
count = 0
for i in a:
count += 1
print(count)
我們來看一下函數(shù)的定義在內(nèi)存空間發(fā)生了什么:
內(nèi)存開辟了一個(gè)空間,但是里邊存放是代碼.
這樣我就將咱們寫的代碼封裝起來了,我們現(xiàn)在執(zhí)行一下程序看看它會(huì)不會(huì)進(jìn)行求長度,它并沒有執(zhí)行,我們來看看怎么能夠執(zhí)行上呢?
使用函數(shù)名加小括號(hào)就可以調(diào)用了 寫法:函數(shù)名() 這個(gè)時(shí)候函數(shù)的函數(shù)體會(huì)被執(zhí)行
def len():
a = "alexdsb"
count = 0
for i in a:
count += 1
print(count)
len() # 函數(shù)的調(diào)用
當(dāng)我們調(diào)用執(zhí)行的時(shí)候,才會(huì)執(zhí)行func這個(gè)空間里的代碼,執(zhí)行的時(shí)候在開辟空間,這次是在func里邊開辟的空間
現(xiàn)在就實(shí)現(xiàn)了求一次長度,我想要多求幾次我就只需要
len()
len()
len()
直接調(diào)用定義好的函數(shù)就可以了
當(dāng)我們執(zhí)行完函數(shù)后,函數(shù)里開辟的空間就銷毀了,我們?nèi)绻胗煤瘮?shù)里的值就需要從函數(shù)中傳遞出來
參數(shù),也就是函數(shù)括號(hào)里的內(nèi)容 函數(shù)在調(diào)用的時(shí)候指定一個(gè)具體的變量的值 就是參數(shù).寫法如下:
def 函數(shù)名(參數(shù)):
函數(shù)體
我們應(yīng)該把代碼改一下,能夠?qū)崿F(xiàn)我剛說的那種效果
def yue(app):
print("拿出?手機(jī)")
print("打開"+app)
print("搜一下宋冬野")
print("戴上耳機(jī)聽一聽")
yue("網(wǎng)易云")
yue("酷我")
yue("酷狗")
搞定了. 我們在調(diào)用yue的時(shí)候給app一個(gè)值. 然后再執(zhí)行函數(shù)體.
如果我們再定函數(shù)的時(shí)候?qū)懥诵螀?在調(diào)用函數(shù)的時(shí)候沒有傳遞值,調(diào)用的時(shí)候右邊括號(hào)會(huì)發(fā)黃,所以我們必須要傳遞參數(shù),參數(shù)要一一對應(yīng),不能多不能少.
? 1.形參
寫在函數(shù)聲明的位置的變量叫形參,形式上的一個(gè)完整.表示這個(gè)函數(shù)需要xxx
2.實(shí)參
在函數(shù)調(diào)用的時(shí)候給函數(shù)傳遞的值.加實(shí)參,實(shí)際執(zhí)行的時(shí)候給函數(shù)傳遞的信息.表示給函數(shù)xxx
3.傳參
從調(diào)用函數(shù)的時(shí)候?qū)⒅祩鬟f到定義函數(shù)的過程叫做傳參
def yue(app): # app 形參
print("拿出?手機(jī)")
print("打開"+app)
print("搜一下宋冬野")
print("戴上耳機(jī)聽一聽")
yue("酷我") # "酷我"在這里就是實(shí)參
len("酷狗") # "字符串"在這里就是實(shí)參
print("網(wǎng)易云") # "麻花藤"就是實(shí)參
def yue(chat,addr,age): # chat 形參
print("拿出手機(jī)")
print("打開"+chat)
print("找個(gè)" + addr +"附近漂亮的" + str(age) + "歲妹子")
print("約不約")
yue("陌陌","北京",18) # 實(shí)參
結(jié)果:
拿出手機(jī)
打開陌陌
找個(gè)北京附近漂亮的18歲妹子
約不約
上述代碼分析: 在訪問yue()的時(shí)候,我們按照位置的順序分別把"陌陌","北京",18賦值給了chat,addr,age,在傳參過程中.系統(tǒng)會(huì)按照位置把實(shí)參賦值到形參.
形參就是一個(gè)變量名,實(shí)參就是值 傳參就是在賦值
def func(addr,age):
addr = "北京"
age = 18 # 從實(shí)參到形參的過程中,函數(shù)體內(nèi)部幫我做了變量的賦值
print(addr)
print(age)
func("北京",18)
練習(xí)
編寫函數(shù),給函數(shù)傳遞兩個(gè)參數(shù)a,b a,b相加 返回a參數(shù)和b參數(shù)相加的和
def f(a,b):
c = a+b
return c
num_sum = f(5,8)
print(num_sum)
結(jié)果: 13
編寫函數(shù),給函數(shù)傳遞兩個(gè)參數(shù)a,b 比較a,b的大小 返回a,b中最大的那個(gè)數(shù)
def f(a,b):
if a>b:
return a
else:
return b
num_sum = f(5,8)
print(num_sum)
結(jié)果:8
比較大小的這個(gè)寫法有點(diǎn)麻煩,我們在這里學(xué)一個(gè)三元運(yùn)算符
def f(a,b):
c = a if a > b else b #當(dāng)a>b就把a(bǔ)賦值給c,否則就把b賦值給c
return c
msg = f(5,7)
print(msg)
結(jié)果:
7
位置參數(shù)好不好呢? 如果是少量的參數(shù)還算OK, 沒有問題. 但是如果函數(shù)在定義的時(shí)候參數(shù)非常多怎么辦? 程序員必須記住, 我有哪些參數(shù), 而且還有記住每個(gè)參數(shù)的位置, 否則函數(shù)就不能正常調(diào)用了. 那則么辦呢? python提出了一種叫做關(guān)鍵字參數(shù). 我們不需要記住每個(gè)參數(shù)的位置. 只要記住每個(gè)參數(shù)的名字就可以了
def yue(chat, address, age):
print("拿出手機(jī)")
print("打開"+chat)
print("找個(gè)"+address+"附近漂亮的"+str(age)+"歲妹子")
print("約不約")
yue(chat="微信", age=18, address="北京") # 關(guān)鍵字參數(shù).
結(jié)果:
拿出手機(jī)
打開微信
找個(gè)北京附近漂亮的18歲妹子
約不約
搞定, 這樣就不需要記住繁瑣的參數(shù)位置了.
可以把上面兩種參數(shù)混合著使用. 也就是說在調(diào)用函數(shù)的時(shí)候即可以給出位置參數(shù), 也可以指定關(guān)鍵字參數(shù).
# 混合參數(shù)
yue("微信", age=18, address="上海") # 正確.第一個(gè)位置賦值給chat, 后面的參數(shù)開始指定關(guān)鍵字.
yue(age="18", "微信", address="廣州") # 錯(cuò)誤, 最開始使用了關(guān)鍵字參數(shù), 那么后面的 微信的位置就串了, 容易出現(xiàn)混亂
注意: 在使用混合參數(shù)的時(shí)候, 關(guān)鍵字參數(shù)必須在位置參數(shù)后面
綜上: 在實(shí)參的?角度來看. 分為三種:
位置參數(shù):
位置參數(shù),按照位置來賦值,到目前為止,我們編寫的函數(shù)都是這種
def yue(chat, address, age):
print("拿出手機(jī)")
print("打開"+chat)
print("找個(gè)"+address+"附近漂亮的"+str(age)+"歲妹子")
print("約不約")
默認(rèn)值參數(shù):
在函數(shù)聲明的時(shí)候, 就可以給出函數(shù)參數(shù)的默認(rèn)值. 在調(diào)用的時(shí)候可以 給出具體的值, 也可以不給值, 使?用默認(rèn)值. 比如, 我們錄入咱們班學(xué)生的基本信息. 通過調(diào)查發(fā)現(xiàn). 我們班大部分學(xué)生都是男生. 這個(gè)時(shí) 候就可以給出?一個(gè)sex='男'的默認(rèn)值.
def stu_info(name, age, sex='男'):
print("錄入學(xué)生信息")
print(name, age, sex)
print("錄入完畢")
stu_info("張強(qiáng)", 18)
注意:必須先聲明在位置參數(shù),才能聲明關(guān)鍵字參數(shù)
形參: 函數(shù)的定義中括號(hào)里是形參
實(shí)參: 函數(shù)的調(diào)用括號(hào)里是實(shí)參
位置傳參時(shí) 形參和實(shí)參必須一一對應(yīng)
傳參: 將實(shí)參傳遞給形參的過程就是傳參
函數(shù)的參數(shù):
# 形參: 函數(shù)定義的時(shí)候叫做形參
# 位置參數(shù)
# 默認(rèn)參數(shù)
# 混合參數(shù)
# 實(shí)參: 函數(shù)調(diào)用的時(shí)候叫做實(shí)參
# 位置參數(shù)
# 關(guān)鍵字參數(shù)
# 混合參數(shù)
# 傳參: 將實(shí)參傳遞給形參的過程叫做傳參
動(dòng)態(tài)參數(shù)分為兩種:動(dòng)態(tài)接受位置參數(shù) *args,動(dòng)態(tài)接收關(guān)鍵字參數(shù)**kwargs.
動(dòng)態(tài)接收位置參數(shù):*args
我們按照上面的例子繼續(xù)寫,如果我請你吃的內(nèi)容很多,但是我又不想用多個(gè)參數(shù)接收,那么我就可以使用動(dòng)態(tài)參數(shù)*args
def eat(*args):
print('我請你吃:',args)
eat('蒸羊羔兒','蒸熊掌','蒸鹿尾兒','燒花鴨','燒雛雞','燒子鵝')
# 運(yùn)行結(jié)果:
#我請你吃: ('蒸羊羔兒', '蒸熊掌', '蒸鹿尾兒', '燒花鴨', '燒雛雞', '燒子鵝')
解釋一下上面參數(shù)的意義:首先來說args,args就是一個(gè)普通的形參,但是如果你在args前面加一個(gè),那么就擁有了特殊的意義:在python中除了表示乘號(hào),他是有魔法的。+args,這樣設(shè)置形參,那么這個(gè)形參會(huì)將實(shí)參所有的位置參數(shù)接收,放置在一個(gè)元組中,并將這個(gè)元組賦值給args這個(gè)形參,這里起到魔法效果的是 而不是args,a也可以達(dá)到剛才效果,但是我們PEP8規(guī)范中規(guī)定就使用args,約定俗成的。
練習(xí):傳入函數(shù)中數(shù)量不定的int型數(shù)據(jù),函數(shù)計(jì)算所有數(shù)的和并返回。
def my_max(*args):
n = 0
for i in args:
n += i
return n
動(dòng)態(tài)接收關(guān)鍵字參數(shù):kwargs**
實(shí)參角度有位置參數(shù)和關(guān)鍵字參數(shù)兩種,python中既然有*args可以接受所有的位置參數(shù)那么肯定也有一種參數(shù)接受所有的關(guān)鍵字參數(shù),那么這個(gè)就是kwargs,同理這個(gè)是具有魔法用法的,kwargs約定俗成使用作為形參。舉例說明:**kwargs,是接受所有的關(guān)鍵字參數(shù)然后將其轉(zhuǎn)換成一個(gè)字典賦值給kwargs這個(gè)形參。
def func(**kwargs):
print(kwargs) # {'name': '太白金星', 'sex': '男'}
func(name='太白金星',sex='男')
我們看一下動(dòng)態(tài)參數(shù)的完成寫法:
def func(*args,**kwargs):
print(args) # ('蒸羊羔兒', '蒸熊掌', '蒸鹿尾兒')
print(kwargs) # {'name': '太白金星', 'sex': '男'}
func('蒸羊羔兒', '蒸熊掌', '蒸鹿尾兒',name='太白金星',sex='男')
如果一個(gè)參數(shù)設(shè)置了動(dòng)態(tài)參數(shù),那么他可以接受所有的位置參數(shù),以及關(guān)鍵字參數(shù),這樣就會(huì)大大提升函數(shù)拓展性,針對于實(shí)參參數(shù)較多的情況下,解決了一一對應(yīng)的麻煩。
剛才我們研究了動(dòng)態(tài)參數(shù),其實(shí)有的同學(xué)對于魔法用法 * 比較感興趣,那么那的魔性用法不止這么一點(diǎn)用法,我們繼續(xù)研究:
函數(shù)中分為打散和聚合。
函數(shù)外可以處理剩余的元素。
函數(shù)的打散和聚合
剛才我們研究了,在函數(shù)定義時(shí),如果我只定義了一個(gè)形參稱為args,那么這一個(gè)形參只能接受幾個(gè)實(shí)參? 是不是只能當(dāng)做一個(gè)位置參數(shù)對待?它只能接受一個(gè)參數(shù):
def eat(args):
print('我請你吃:',args) # 我請你吃: 蒸羊羔兒
eat('蒸羊羔兒')
但是如果我給其前面加一個(gè)* 那么args可以接受多個(gè)實(shí)參,并且返回一個(gè)元組,對吧? (*kwargs也是同理將多個(gè)關(guān)鍵字參數(shù)轉(zhuǎn)化成一個(gè)字典返回)所以在函數(shù)的定義時(shí): 起到的是聚合的作用。
此時(shí)不著急給大家講這個(gè)打散,而是出一個(gè)小題:你如何將三個(gè)數(shù)據(jù)(這三個(gè)數(shù)據(jù)都是可迭代對象類型)s1 = 'alex',l1 = [1, 2, 3, 4], tu1 = ('武sir', '太白', '女神',)的每一元素傳給動(dòng)態(tài)參數(shù)*args?(就是args最終得到的是 ('a','l','e','x', 1, 2, 3, 4,'武sir', '太白', '女神',)?有人說這還不簡單么?我直接傳給他們不就行了?
s1 = 'alex'
l1 = [1, 2, 3, 4]
tu1 = ('武sir', '太白', '女神',)
def func(*args):
print(args) # ('alex', [1, 2, 3, 4], ('武sir', '太白', '女神'))
func(s1,l1,tu1)
這樣肯定是不行,他會(huì)將這個(gè)三個(gè)數(shù)據(jù)類型當(dāng)成三個(gè)位置參數(shù)傳給args,沒有實(shí)現(xiàn)我的要求。
好像你除了直接寫,沒有別的什么辦法,那么這里就得用到我們的魔法用法 :*
s1 = 'alex'
l1 = [1, 2, 3, 4]
tu1 = ('武sir', '太白', '女神',)
def func(*args):
print(args) # ('a', 'l', 'e', 'x', 1, 2, 3, 4, '武sir', '太白', '女神')
func(*s1,*l1,*tu1)
你看此時(shí)是函數(shù)的執(zhí)行時(shí),我將你位置參數(shù)的實(shí)參(可迭代類型)前面加上,相當(dāng)于將這些實(shí)參給拆解成一個(gè)一個(gè)的組成元素當(dāng)成位置參數(shù),然后傳給args,這時(shí)候這個(gè)好像取到的是打散的作用。所以在函數(shù)的執(zhí)行時(shí):,**起到的是打散的作用。
dic1 = {'name': '太白', 'age': 18}
dic2 = {'hobby': '喝茶', 'sex': '男'}
def func(**kwargs):
print(kwargs) # {'name': '太白', 'age': 18, 'hobby': '喝茶', 'sex': '男'}
func(**dic1,**dic2)
*處理剩下的元素
*除了在函數(shù)中可以這樣打散,聚合外,函數(shù)外還可以靈活的運(yùn)用:
# 之前講過的分別賦值
a,b = (1,2)
print(a, b) # 1 2
# 其實(shí)還可以這么用:
a,*b = (1, 2, 3, 4,)
print(a, b) # 1 [2, 3, 4]
*rest,a,b = range(5)
print(rest, a, b) # [0, 1, 2] 3 4
print([1, 2, *[3, 4, 5]]) # [1, 2, 3, 4, 5]
到目前為止,從形參的角度我們講了位置參數(shù),默認(rèn)值參數(shù),動(dòng)態(tài)參數(shù)*args,**kwargs,還差一種參數(shù),需要講完形參順序之后,引出。先不著急,我們先看看已經(jīng)講的這些形參他的排列順序是如何的呢?
首先,位置參數(shù),與默認(rèn)參數(shù)他兩個(gè)的順序我們昨天已經(jīng)確定了,位置參數(shù)必須在前面,即 :位置參數(shù),默認(rèn)參數(shù)。
那么動(dòng)態(tài)參數(shù)*args,**kwargs放在哪里呢?
動(dòng)態(tài)參數(shù)*args,肯定不能放在位置參數(shù)前面,這樣我的位置參數(shù)的參數(shù)就接收不到具體的實(shí)參了:
# 這樣位置參數(shù)a,b始終接收不到實(shí)參了,因?yàn)閍rgs全部接受完了
def func(*args,a,b,sex='男'):
print(args)
print(a,b)
func(1, 2, 3, 4, 5)
那么動(dòng)態(tài)參數(shù)必須在位置參數(shù)后面,他可以在默認(rèn)參數(shù)后面么?
# 這樣也不行,我的實(shí)參的第三個(gè)參數(shù)始終都會(huì)將sex覆蓋掉,這樣失去了默認(rèn)參數(shù)的意義。
def func(a,b,sex='男',*args,):
print(args) # (4, 5)
print(sex) # 3
print(a,b) # 1 2
func(1, 2, 3, 4, 5)
所以*args一定要在位置參數(shù)與默認(rèn)值參數(shù)中間:位置參數(shù),*args,默認(rèn)參數(shù)。
那么我的kwargs放在哪里?kwargs可以放在默認(rèn)參數(shù)前面么?
# 直接報(bào)錯(cuò):因?yàn)?*kwargs是接受所有的關(guān)鍵字參數(shù),如果你想改變默認(rèn)參數(shù)sex,你永遠(yuǎn)也改變不了,因?yàn)?# 它會(huì)先被**kwargs接受。
def func(a,b,*args,**kwargs,sex='男',):
print(args) # (4, 5)
print(sex) # 3
print(a,b) # 1 2
print(kwargs)
func(1, 2, 3, 4, 5)
所以截止到此:所有形參的順序?yàn)椋何恢脜?shù),*args,默認(rèn)參數(shù),**kwargs。
僅限關(guān)鍵字參數(shù)是python3x更新的新特性,他的位置要放在*args后面,kwargs前面(如果有kwargs),也就是默認(rèn)參數(shù)的位置,它與默認(rèn)參數(shù)的前后順序無所謂,它只接受關(guān)鍵字傳的參數(shù):
# 這樣傳參是錯(cuò)誤的,因?yàn)閮H限關(guān)鍵字參數(shù)c只接受關(guān)鍵字參數(shù)
def func(a,b,*args,c):
print(a,b) # 1 2
print(args) # (4, 5)
# func(1, 2, 3, 4, 5)
# 這樣就正確了:
def func(a,b,*args,c):
print(a,b) # 1 2
print(args) # (3, 4)
print(5)
func(1, 2, 3, 4, c=5)
這個(gè)僅限關(guān)鍵字參數(shù)從名字定義就可以看出他只能通過關(guān)鍵字參數(shù)傳參,其實(shí)可以把它當(dāng)成不設(shè)置默認(rèn)值的默認(rèn)參數(shù)而且必須要傳參數(shù),不傳就報(bào)錯(cuò)。
所以形參角度的所有形參的最終順序?yàn)椋?位置參數(shù),args,默認(rèn)參數(shù),僅限關(guān)鍵字參數(shù),kwargs。
課間考一道題:
def foo(a,b,*args,c,sex=None,**kwargs):
print(a,b)
print(c)
print(sex)
print(args)
print(kwargs)
# foo(1,2,3,4,c=6)
# foo(1,2,sex='男',name='alex',hobby='old_woman')
# foo(1,2,3,4,name='alex',sex='男')
# foo(1,2,c=18)
# foo(2, 3, [1, 2, 3],c=13,hobby='喝茶')
# foo(*[1, 2, 3, 4],**{'name':'太白','c':12,'sex':'女'})
接下來我們講的內(nèi)容,理論性的偏多,就是從空間角度,內(nèi)存級別去研究python。首先我們看看什么是全局名稱空間:
在python解釋器開始執(zhí)行之后, 就會(huì)在內(nèi)存中開辟一個(gè)空間, 每當(dāng)遇到一個(gè)變量的時(shí)候, 就把變量名和值之間的關(guān)系記錄下來, 但是當(dāng)遇到函數(shù)定義的時(shí)候, 解釋器只是把函數(shù)名讀入內(nèi)存, 表示這個(gè)函數(shù)存在了, 至于函數(shù)內(nèi)部的變量和邏輯, 解釋器是不關(guān)心的. 也就是說一開始的時(shí)候函數(shù)只是加載進(jìn)來, 僅此而已, 只有當(dāng)函數(shù)被調(diào)用和訪問的時(shí)候, 解釋器才會(huì)根據(jù)函數(shù)內(nèi)部聲明的變量來進(jìn)行開辟變量的內(nèi)部空間. 隨著函數(shù)執(zhí)行完畢, 這些函數(shù)內(nèi)部變量占用的空間也會(huì)隨著函數(shù)執(zhí)行完畢而被清空.
我們首先回憶一下Python代碼運(yùn)行的時(shí)候遇到函數(shù)是怎么做的,從Python解釋器開始執(zhí)行之后,就在內(nèi)存中開辟里一個(gè)空間,每當(dāng)遇到一個(gè)變量的時(shí)候,就把變量名和值之間對應(yīng)的關(guān)系記錄下來,但是當(dāng)遇到函數(shù)定義的時(shí)候,解釋器只是象征性的將函數(shù)名讀如內(nèi)存,表示知道這個(gè)函數(shù)存在了,至于函數(shù)內(nèi)部的變量和邏輯,解釋器根本不關(guān)心。
等執(zhí)行到函數(shù)調(diào)用的時(shí)候,Python解釋器會(huì)再開辟一塊內(nèi)存來儲(chǔ)存這個(gè)函數(shù)里面的內(nèi)容,這個(gè)時(shí)候,才關(guān)注函數(shù)里面有哪些變量,而函數(shù)中的變量會(huì)儲(chǔ)存在新開辟出來的內(nèi)存中,函數(shù)中的變量只能在函數(shù)內(nèi)部使用,并且會(huì)隨著函數(shù)執(zhí)行完畢,這塊內(nèi)存中的所有內(nèi)容也會(huì)被清空。
我們給這個(gè)‘存放名字與值的關(guān)系’的空間起了一個(gè)名字-------命名空間。
代碼在運(yùn)行伊始,創(chuàng)建的存儲(chǔ)“變量名與值的關(guān)系”的空間叫做全局命名空間;
在函數(shù)的運(yùn)行中開辟的臨時(shí)的空間叫做局部命名空間也叫做臨時(shí)名稱空間。
現(xiàn)在我們知道了,py文件中,存放變量與值的關(guān)系的一個(gè)空間叫做全局名稱空間,而當(dāng)執(zhí)行一個(gè)函數(shù)時(shí),內(nèi)存中會(huì)臨時(shí)開辟一個(gè)空間,臨時(shí)存放函數(shù)中的變量與值的關(guān)系,這個(gè)叫做臨時(shí)名稱空間,或者局部名稱空間。
其實(shí)python還有一個(gè)空間叫做內(nèi)置名稱空間:內(nèi)置名稱空間存放的就是一些內(nèi)置函數(shù)等拿來即用的特殊的變量:input,print,list等等,所以,我們通過畫圖捋一下:
那么這就是python中經(jīng)常提到的三個(gè)空間。
總結(jié):
\1. 全局命名空間--> 我們直接在py文件中, 函數(shù)外聲明的變量都屬于全局命名空間
\2. 局部命名空間--> 在函數(shù)中聲明的變量會(huì)放在局部命名空間
\3. 內(nèi)置命名空間--> 存放python解釋器為我們提供的名字, list, tuple, str, int這些都是內(nèi)置命名空間
所謂的加載順序,就是這三個(gè)空間加載到內(nèi)存的先后順序,也就是這個(gè)三個(gè)空間在內(nèi)存中創(chuàng)建的先后順序,你想想他們能是同時(shí)創(chuàng)建么?肯定不是的,那么誰先誰后呢?我們捋順一下:在啟動(dòng)python解釋器之后,即使沒有創(chuàng)建任何的變量或者函數(shù),還是會(huì)有一些函數(shù)直接可以用的比如abs(-1),max(1,3)等等,在啟動(dòng)Python解釋器的時(shí)候,就已經(jīng)導(dǎo)入到內(nèi)存當(dāng)中供我們使用,所以肯定是先加載內(nèi)置名稱空間,然后就開始從文件的最上面向下一行一行執(zhí)行,此時(shí)如果遇到了初始化變量,就會(huì)創(chuàng)建全局名稱空間,將這些對應(yīng)關(guān)系存放進(jìn)去,然后遇到了函數(shù)執(zhí)行時(shí),在內(nèi)存中臨時(shí)開辟一個(gè)空間,加載函數(shù)中的一些變量等等。所以這三個(gè)空間的加載順序?yàn)椋簝?nèi)置命名空間(程序運(yùn)行伊始加載)->全局命名空間(程序運(yùn)行中:從上到下加載)->局部命名空間(程序運(yùn)行中:調(diào)用時(shí)才加載。
取值順序就是引用一個(gè)變量,先從哪一個(gè)空間開始引用。這個(gè)有一個(gè)關(guān)鍵點(diǎn):從哪個(gè)空間開始引用這個(gè)變量。我們分別舉例說明:
# 如果你在全局名稱空間引用一個(gè)變量,先從全局名稱空間引用,全局名# 稱空間如果沒有,才會(huì)向內(nèi)置名稱空間引用。
input = 666
print(input) # 666
# 如果你在局部名稱空間引用一個(gè)變量,先從局部名稱空間引用,
# 局部名稱空間如果沒有,才會(huì)向全局名稱空間引用,全局名稱空間在沒有,就會(huì)向內(nèi)置名稱空間引用。
input = 666
print(input) # 666
input = 666
def func():
input = 111
print(input) # 111
func()
所以空間的取值順序與加載順序是相反的,取值順序滿足的就近原則,從小范圍到大范圍一層一層的逐步引用。
作用域就是作用范圍, 按照生效范圍來看分為全局作用域和局部作用域
全局作用域: 包含內(nèi)置命名空間和全局命名空間. 在整個(gè)文件的任何位置都可以使用(遵循 從上到下逐?執(zhí)行).
局部作用域: 在函數(shù)內(nèi)部可以使用.
作?域命名空間:
1. 全局作用域: 全局命名空間 + 內(nèi)置命名空間
2. 局部作?域: 局部命名空間
這兩個(gè)內(nèi)置函數(shù)放在這里講是在合適不過的,他們就直接可以反映作用域的內(nèi)容,有助于我們理解作用域的范圍。
globals(): 以字典的形式返回全局作用域所有的變量對應(yīng)關(guān)系。
locals(): 以字典的形式返回當(dāng)前作用域的變量的對應(yīng)關(guān)系。
這里一個(gè)是全局作用域,一個(gè)是當(dāng)前作用域,一定要分清楚,接下來,我們用代碼驗(yàn)證:
# 在全局作用域下打印,則他們獲取的都是全局作用域的所有的內(nèi)容。
a = 2
b = 3
print(globals())
print(locals())
'''
{'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001806E50C0B8>,
'__spec__': None, '__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>,
'__file__': 'D:/lnh.python/py project/teaching_show/day09~day15/function.py',
'__cached__': None, 'a': 2, 'b': 3}
'''
# 在局部作用域中打印。
a = 2
b = 3
def foo():
c = 3
print(globals()) # 和上面一樣,還是全局作用域的內(nèi)容
print(locals()) # {'c': 3}
foo()
標(biāo)題名稱:Python函數(shù)初始
文章路徑:http://aaarwkj.com/article2/ipdgoc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)、標(biāo)簽優(yōu)化、、網(wǎng)站排名、品牌網(wǎng)站建設(shè)、定制開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)