天天看點

python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階

一.今日主要内容總覽(重點)

1.動态傳參(重點) *,**

*:

形參:聚合

位置參數*=>元組

關鍵字**=>字典

實參:打散

清單,字元串,元組=>*

字典=>**

形參順序:

位置,*args,預設值,**kwargs

無敵傳參:

def func(*args,**kwargs): #arguments參數, keyword-arguments關鍵字參數

pass

2.作用域和名稱空間

名稱空間:用來存放名字(變量,函數名,類名,引入的子產品名字)的

1.全局名稱空間:我們在py檔案中自己寫的變量,函數...

2.内置名稱空間:我們python解釋器提供好的一些内置函數(print,input...)

3.局部名稱空間:在我們執行函數的時候,會産生一個局部名稱空間.放的是:函數内部的内容(變量,函數,類...)

名稱空間可能會有無數個,局部名稱空間,相對是獨立的,一般互不幹擾

作用域:

1.全局作用域:内置+全局

2.局部作用域:局部

globals() 檢視全局作用域

locals() 檢視目前作用域

#函數調用完畢,函數開辟的空間自動關閉

#全局不能找局部的變量

#但是局部可以找全局

3.函數的嵌套

在函數中聲明函數

在内部函數中使用變量的時候,查找順序:先找自己=>上一層=>上一層..全局=>内置

4.nonlocal和global關鍵字(重點)

golbal:在局部引入全局變量

nonlocal:在局部...内層函數引入外層離他最近的那個變量

下周預習:

第一類對象(函數名,他就是個變量名),閉包,疊代器

生成器,各種推導式

内置函數1,内置函數2

裝飾器(頭疼),裝飾器進階

子產品 //一個周

面向對象 //一個周

DAY10-函數進階

二.今日内容大綱

1.動态傳參

2.名稱空間&作用域

3.函數的互相調用和函數的嵌套

4.nonlocal&global

三.内容詳解

1.動态傳參

(1)

分别傳遞給形參

defchi(zhushi,cai,fushi,tang,tiandian):print(zhushi,cai,fushi,tang,tiandian)

chi('大碗大米飯','火爆大頭菜','把子肉','蕃茄雞蛋湯','烤地瓜')#吃不夠靈活//

chi('小碗大米飯','火爆大頭菜','','','')#參數不夠報錯或者必須這樣寫

'''結果:

大碗大米飯 火爆大頭菜 把子肉 蕃茄雞蛋湯 烤地瓜

小碗大米飯 火爆大頭菜'''

(2)

形參的順序(重點)

位置參數 *args 預設值參數 **kwargs

以後寫參數.可以随意的進行搭配,但是,順序不能串

*在形參位置,*表示不定參數-接收的是位置參數

在接收到的位置參數的動态傳參:都是元組

def chi(*food): #在形參這裡把傳遞過來的實參進行了聚合,聚合成了元組

print(food)

chi('小米粥')

chi('小米粥','鹹鴨蛋')

chi('爆米花','鹹鴨蛋','辣白菜')

chi('小米粥','爆米花','鹹鴨蛋','蒜茄子')'''結果:

('小米粥',)

('小米粥', '鹹鴨蛋')

('爆米花', '鹹鴨蛋', '辣白菜')

('小米粥', '爆米花', '鹹鴨蛋', '蒜茄子')

(3)

位置參數放在前面,動态位置參數放在後邊

解釋後邊的*args會聚合 4,5,6,7形成一個元組

def func(a,b,c,*args):print(a,b,c,args)

func(1,2,3,4,5,6,7)'''結果:

1 2 3 (4, 5, 6, 7)'''

(4)

動态位置參數放在前面,預設參數放在後邊

def func(*args,a,b,c):print(a,b,c,args)

func(1,2,3,4,5,6,7,a=8,b=9,c=10)'''結果:#注意位置

8 9 10 (1, 2, 3, 4, 5, 6, 7)

(5)

key word arguments #關鍵字參數

**在形參中表示動态傳參-關鍵字傳遞參數

關鍵字動态傳參接收到的是字典

(5-1)

def func(**kwargs): #也是聚合 ** 聚合成字典

print(kwargs)

func(1,2,3,4,5)

'''

報錯結果分析:(位置參數,報錯)

表面上不報錯,但是運作起來會報錯

func() takes 0 positional arguments but 5 were given

func()采用0個位置參數,但給出了5個

(5-2)

def func(**kwargs): #也是聚合 ** 聚合成字典

print(kwargs)

func(a=1,b=2,c=3,haha='呵呵',good='not bad')#這裡必須是關鍵字傳參,不能是位置傳參

'''# 結果:

{'a': 1, 'b': 2, 'c': 3, 'haha': '呵呵', 'good': 'not bad'}'''

(6)

#預設值不生效,下面兩種寫法都可以

正确寫法def func(gender='男',**kwargs):print(gender,kwargs)

func(gender='女',a=5,b=6,c=7)

func('女',a=5,b=6,c=7)

錯誤寫法def func(**kwargs,gender='男'):print(gender,kwargs)

func(gender='女',a=5,b=6,c=7)

func('女',a=5,b=6,c=7)

重點:

形式參數的順序:

位置參數 *args 預設值 **kwargs

以後寫參數,可以随意的進行搭配,但是必須按照上邊的順序

(7)

無敵傳參案例

實參,不進行傳遞參數也是可以的

def func(*args,**kwargs): #參數沒有限制,随便傳遞

print(args)print(kwargs)

func(1,2,3,4,5,a=3,b=5)

#結果:

(1, 2, 3, 4, 5)

{'a': 3, 'b': 5}

(8)

for循環隻能縱向打散,不能橫向打散

這裡是形參 *代表聚合

(8-1)

def chi(*food):print(food)

lst=['胡蘿蔔','大白菜','大蘿蔔','草','果凍']#這裡是實參 代表打散

chi(*lst)'''結果:('胡蘿蔔', '大白菜', '大蘿蔔', '草', '果凍')'''

(8-2)

def chi(*food):print(food)

lst=['胡蘿蔔','大白菜','大蘿蔔','草','果凍']for el inlst:

chi(el)'''# 結果:

# ('胡蘿蔔',)

# ('大白菜',)

# ('大蘿蔔',)

# ('草',)

# ('果凍',)'''

(8-3)

def chi(*food):print(food)

lst=['胡蘿蔔','大白菜','大蘿蔔','草','果凍']

chi(lst[0],lst[1],lst[2],lst[3],lst[4],)'''結果:('胡蘿蔔', '大白菜', '大蘿蔔', '草', '果凍')'''

(8-4)

字元串疊代元素換成元組

def chi(*food):print(food)

chi(*'你今天吃了什麼') #打散,把清單,元組,字元串打散成位置參數進行傳遞

s='冬瓜'chi(s)

chi(*s)

chi('紅鯉魚','綠鯉魚','驢')

結果:

結果:#字元串疊代元素換成元組

('你', '今', '天', '吃', '了', '什', '麼')

('冬瓜',) #直接傳是這樣

('冬', '瓜') #聚合是這樣

('紅鯉魚', '綠鯉魚', '驢')

(8-5)

和8-4的最後一例一樣

和8-4的最後一例一樣def chi(*food):print(food)

chi('大白菜','大冬瓜')'''結果:('大白菜', '大冬瓜')'''

(9)

(9-1)#三種調用寫法

def chi(**food): #聚合,聚合成字典

print(food)

dic={'主食':'面條','副食':'洋芋泥','湯':'疙瘩湯'}

chi(**dic)

chi(**dic, 甜點="冰激淩") #打散. 打散成關鍵字

chi(主食="面條", 副食="洋芋泥", 湯="疙瘩湯", 甜點="冰激淩")

chi(主食='面條',副食='洋芋泥',湯='疙瘩湯')'''結果:

{'主食': '面條', '副食': '洋芋泥', '湯': '疙瘩湯'}

{'主食': '面條', '副食': '洋芋泥', '湯': '疙瘩湯', '甜點': '冰激淩'}

{'主食': '面條', '副食': '洋芋泥', '湯': '疙瘩湯', '甜點': '冰激淩'}

{'主食': '面條', '副食': '洋芋泥', '湯': '疙瘩湯'}'''

總結:

動态傳參*總結:

形參:

*->元組,

**->字典 表示聚合

實參:

*->清單,字元串,元組

**->字典 表示打散

2.名稱空間&作用域

(1)引入

a=10lst=[1,2,3,4]#内置函數print

print('你好啊,我叫蓋倫')

(2)

defchi():

a= 10b= 20

# 如果不調用chi() chi中的a和b都不會建立

# 如果調用了chi() 會建立a,b變量,也就是兩個小空間

chi()

(3)

defchi():

a= 10

print(a)

chi()print(a) #在沒有其他條件的情況下,外部不可以調用内部變量,所有報錯

(4)

def print(b):passa= 10

defchi():print(a)

chi()

總結:

從全局去找局部->找不到

局部去找全局-> 可以找到

(5)

名稱空間可以有無數個

資料結構推薦:C嚴蔚敏

内置名稱空間第一層,全局名稱空間是第二層,局部名稱空間是第三層

從第三層到第一層開始找

(6)

a=10b=20

def今天有是星期五了():pass今天有是星期五了()print(globals())

#檢視全局作用域中的内容#globals 全局作用域:内置+全局名稱空間

'''結果:

{'__name__': '__main__',

'__doc__': None,

'__package__': None,

'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000170913EB438>,

'__spec__': None,

'__annotations__': {},

'__builtins__': ,

'__file__': 'F:/Python_workspace_S18/day10 函數的進階/04 名稱空間和作用域.py',

'__cached__': None,

'a': 10, 'b': 20,

'今天有是星期五了': }'''

#自己寫的全局變量:#'a': 10, 'b': 20,#'今天有是星期五了': }

(7)

defchi():

a=20b=30

#print(locals()) #檢視目前作用域中的内容

print(globals())#alex,老男孩兒, 武sir, 全局作用域中的内容,在這裡不顯示a和b了

#我們可以知道不建立,在全局作用域内找不到局部作用域中的内容

chi()'''結果:

{'b': 30, 'a': 20}

{'__name__': '__main__',

'__doc__': None, '__package__': None,

'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000026EB5D4B438>,

'__spec__': None,

'__annotations__': {},

'__builtins__': ,

'__file__': 'F:/Python_workspace_S18/day10 函數的進階/04 名稱空間和作用域.py',

'__cached__': None,

'chi': }'''

#print(locals()) # 全局#print(globals()) # 全局

3.函數的互相調用和函數的嵌套

(1)函數的互相調用

deffunc1():print("我是神器的func1")deffunc2():

func1()print("我是神器的func2")deffunc3():print("我是神器的func3")#func5()

deffunc4():

func3()print("我是神器的func4")deffunc5():

func2()

func3()print("我是神器的func5")deffunc6():

func5()print("我是神器的func6")

func3()

func1()

func6()

結果:

'''結果:

我是神器的func1

我是神器的func2

我是神器的func3

我是神器的func5

我是神器的func6

我是神器的func3

我是神器的func1'''

(2)函數的嵌套

(2-1)

defouter():definner():print("我的天哪")print("還可以這樣寫???")

inner()

outer()'''結果:

還可以這樣寫???

我的天哪'''

#inner() # 在全局不能找到局部的内容,是以不能直接寫在外邊

(2-2)

python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階
python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階

deffunc1():print("1")deffunc2():print("2")deffunc3():print("3")print("4")

func3()print(5)print("6")

func2()print("7")

func1()

View Code

結果:

python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階
python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階

1

6

2

4

3

5

7

View Code

4.nonlocal&global

(1)

global是在内部修改全局

全局變量一般是不能随意的修改的

a = 10

deffunc():#慎用.

global a # 重點記憶:global 表示從全局把一個變量引入到局部, 後面使用的a都是全局變量

a += 10 #?? a = a + 10 # 現在的a是全局的, 你現在視圖改全局變量

print("裡面的列印",a)

func()print("外面的列印", a)'''結果:

裡面的列印 20

外面的列印 20'''

(2)

nonlocal 在局部, 尋找離他最近的外層的一個變量

a = 50

deffunc1():

a= 10 #局部,如果這裡沒有a=10,會報錯

deffunc2():

nonlocal a#不找全局,隻能找外層函數中的, global找全局

a += 10 #a = a + 10 python不讓這麼幹

print("func2", a)

func2()print(a)

func1()print(a)

結果:

func220

20

50

(3)

#不管是多少層.globals都是找全局裡的

#全局變量一般是不能随意的修改的

#注意:nonlocal不能找全局變量

# nonlocal 在局部,尋找離他最近的外層的一個變量

# 如果沒有nonlocal和global 查找的順序: 自己, 上一層, 上一層, 上一層

deffunc1():

a=10 #局部

deffunc2():

nonlocal a

a=30

print('func2',a)

func2()print(a)

func1()'''結果:

func2 30

30'''

(4)真假難辨,這種題都能做出來,還有什麼題目不能做出來

a = 1

deffun_1():

a= 2

deffun_2():

nonlocal a

a= 3

deffun_3():

a= 4

print(a)print(a)

fun_3()print(a)print(a)

fun_2()print(a)print(a)

fun_1()print(a)

結果:

python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階
python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階

結果:1

2

3

4

3

3

1

View Code

(5)折疊調用

deflogin():globalflag

uname= input("使用者名:")

upwd= input("密碼:")if uname == "alex" and upwd == "123":

flag=Trueelse:

flag=Falsedeffatie():if flag ==True:print("可以發帖")else:print("滾去登入")

login()

fatie()

今日作業:

2,寫函數,接收n個數字,求這些參數數字的和。(動态傳參)

python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階
python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階

方法一:def digit_sum(*args):print(sum(args))

digit_sum(1,2,3,4,5)

方法二:def digit_sum(*args):

sum=0for i inargs:

sum+=iprint(sum)

digit_sum(1,2,3,4,5)

View Code

3,讀代碼,回答:代碼中,列印出來的值a,b,c分别是什麼?為什麼?

a=10

b=20

def test5(a,b):

print(a,b)

c = test5(b,a) #c代表的是傳回值

print(c)

python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階
python蟒蛇代碼解析_巨蟒python全棧開發-第10天 函數進階

a是20

b是10

c是None

結果是:20 10None

View Code

4,讀代碼,回答:代碼中,列印出來的值a,b,c分别是什麼?為什麼?

a=10

b=20

def test5(a,b):

a=3

b=5

print(a,b)

c = test5(b,a)

print(c)

print(a,b)

列印出來的結果

a是3 b是5

None

a是10 b是20

5,寫函數,傳入函數中多個實參(均為可疊代對象如字元串,清單,元祖,集合等),

将每個實參的每個元素依次添加到函數的動态參數args裡面.

例如 傳入函數兩個參數[1,2,3] (22,33)最終args為(1,2,3,22,33)

這裡必須要對清單或者元組進行打散才可以def pa(*args): #1

#print(args)

return args #2#a=pa([1,2,3],(22,33)) #結果:([1, 2, 3], (22, 33))

x=[1,2,3] #3

y=(22,33) #4

a=pa(*x,*y) #5

print(a) #6

6,寫函數,傳入函數中多個實參(實參均為字典),

将每個實參的鍵值對依次添加到函數的動态參數kwargs裡面.

例如 傳入函數兩個參數{‘name’:’alex’} {‘age’:1000}

最終kwargs為{‘name’:’alex’ ,‘age’:1000}

#注意,必須要接受參數

def a(**kwargs):returnkwargs

x={'name':'alex'}

y={'age':1000}

b=a(**x,**y)print(b)

7, 下面代碼成立麼?如果不成立為什麼報錯?怎麼解決?

7.1a= 2

defwrapper():print(a)

wrapper()#正确

7.2a= 2

defwrapper():

a+= 1

print(a)

wrapper()#錯誤,在指派前引用全局變量a

修改後的程式

a= 2

defwrapper():globala

a+= 1

print(a)

wrapper()7.3

defwrapper():

a= 1

definner():print(a)

inner()

wrapper()#正确

7.4

defwrapper():

a= 1

definner():

a+= 1

print(a)

inner()

wrapper()#錯誤,在指派前引用全局變量a

#修改後的結果

defwrapper():

a= 1

definner():

nonlocal a

a+= 1

print(a)

inner()

wrapper()

8,寫函數,接收兩個數字參數,将較小的數字傳回.

deffunc(a,b):if a>b:returnbelse:returna

x=func(2,3)print(x)

9,寫函數,接收一個參數(此參數類型必須是可疊代對象),

将可疊代對象的每個元素以’_’相連接配接,形成新的字元串,并傳回.

例如 傳入的可疊代對象為[1,'老男孩','武sir']傳回的結果為’1_老男孩_武sir’

deffunc(x):

s=''

for i inx:

i=str(i)

s+=i +"_"

return s.strip('_')

a=func([1,'老男孩','武sir'])print(a)

10,寫函數,傳入n個數,傳回字典{‘max’:最大值,’min’:最小值}

例如:min_max(2,5,7,8,4) 傳回:{‘max’:8,’min’:2}(此題用到max(),min()内置函數)

def func(*args):return {'max':max(args),'min':min(args)}

a=func(*(2,5,7,8,4))print(a)

11,寫函數,傳入一個參數n,傳回n的階乘

例如:cal(7) 計算7*6*5*4*3*2*1

defcal(n):if n==0:return 1

return n * cal(n - 1)

a=cal(3)print(a)

12寫函數,傳回一個撲克牌清單,裡面有52項,每一項是一個元組

例如:[(‘紅心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]

defpuke():

a=['紅心','草花','梅花','黑桃']

b=[2,3,4,5,6,7,8,9,10,'J','Q','K','A']

lst=[]for i inb:for k ina:

lst.append((k,i))returnlst

a=puke()print(a)

13 有如下函數:

def wrapper():

def inner():

print(666)

wrapper()

你可以任意添加代碼,用兩種或以上的方法,執行inner函數.

方法一defwrapper():definner():print(666)

inner()

wrapper()

方法二defwrapper():definner():print(666)returninner

wrapper()()

14相關面試題(先從紙上寫好答案,然後在運作):

1,有函數定義如下:

def calc(a,b,c,d=1,e=2):

return (a+b)*(c-d)+e

請分别寫出下列标号代碼的輸出結果,如果出錯請寫出Error。

print(calc(1,2,3,4,5))__2___

print(calc(1,2))__Error__

print(calc(e=4,c=5,a=2,b=3))_24__

print(calc(1,2,3))__8___

print(calc(1,2,3,e=4))__10__

print(calc(1,2,3,d=5,4))__Error___

2,(此題有坑)下面代碼列印的結果分别是__[10,'a']___,__[123]___,___[10,'a']__.

def extendList(val,list=[]):  #多次調用使用同一個清單

list.append(val)     #把元素添加到清單,然後傳回清單

return list

list1 = extendList(10)

list2 = extendList(123,[])

list3 = extendList('a')

print('list1=%s'%list1)

print('list2=%s'%list2)

print('list3=%s'%list3)

3, 寫代碼完成99乘法表.(更新題)

1 * 1 = 1

2 * 1 = 2 2 * 2 = 4

3 * 1 = 3 3 * 2 = 6 3 * 3 = 9

......

9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81

'''

雙for循環實作:

for i in range(1,10):for j in range(1,i+1):

r=i*jprint('%s*%s=%s'%(i,j,r),' ',end='')print()