一.今日主要内容總覽(重點)
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)

deffunc1():print("1")deffunc2():print("2")deffunc3():print("3")print("4")
func3()print(5)print("6")
func2()print("7")
func1()
View Code
結果:

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)
結果:

結果: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個數字,求這些參數數字的和。(動态傳參)

方法一: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)

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()