一.今日主要內容總覽(重點)
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
裝飾器(頭疼),裝飾器進階
模塊 //一個周
面向對象 //一個周
二.今日內容大綱
1.動態傳參
2.名稱空間&做用域
3.函數的互相調用和函數的嵌套
4.nonlocal&global
三.內容詳解
1.動態傳參
(1)
分別傳遞給形參
def chi(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 in lst: 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('紅鯉魚','綠鯉魚','驢')
結果:python
結果:#字符串迭代元素換成元組 ('你', '今', '天', '吃', '了', '什', '麼') ('冬瓜',) #直接傳是這樣 ('冬', '瓜') #聚合是這樣 ('紅鯉魚', '綠鯉魚', '驢')
(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(主食='麪條',副食='土豆泥',湯='疙瘩湯') ''' 結果: {'主食': '麪條', '副食': '土豆泥', '湯': '疙瘩湯'} {'主食': '麪條', '副食': '土豆泥', '湯': '疙瘩湯', '甜點': '冰激凌'} {'主食': '麪條', '副食': '土豆泥', '湯': '疙瘩湯', '甜點': '冰激凌'} {'主食': '麪條', '副食': '土豆泥', '湯': '疙瘩湯'} '''
總結:git
動態傳參*總結:
形參:
*->元組,
**->字典 表示聚合
實參:
*->列表,字符串,元組
**->字典 表示打散
2.名稱空間&做用域
(1)引入
a=10 lst=[1,2,3,4] #內置函數print print('你好啊,我叫蓋倫')
(2)
def chi(): a = 10 b = 20 # 若是不調用chi() chi中的a和b都不會建立 # 若是調用了chi() 會建立a,b變量,也就是兩個小空間 chi()
(3)
def chi(): a = 10 print(a) chi() print(a) # 在沒有其餘條件的狀況下,外部不能夠調用內部變量,全部報錯
(4)
def print(b): pass a = 10 def chi(): print(a) chi()
總結: 從全局去找局部 -> 找不到 局部去找全局 -> 能夠找到
(5)
名稱空間能夠有無數個
數據結構推薦:C嚴蔚敏
內置名稱空間第一層,全局名稱空間是第二層,局部名稱空間是第三層
從第三層到第一層開始找
(6)
a=10 b=20 def 今天有是星期五了(): pass 今天有是星期五了() print(globals())
#查看全局做用域中的內容 #globals 全局做用域:內置+全局名稱空間 ''' 結果: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000170913EB438>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:/Python_workspace_S18/day10 函數的進階/04 名稱空間和做用域.py', '__cached__': None, 'a': 10, 'b': 20, '今天有是星期五了': <function 今天有是星期五了 at 0x0000017091391E18>} ''' #本身寫的全局變量: # 'a': 10, 'b': 20, # '今天有是星期五了': <function 今天有是星期五了 at 0x0000017091391E18>}
(7)
def chi(): a=20 b=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__': <module 'builtins' (built-in)>, '__file__': 'F:/Python_workspace_S18/day10 函數的進階/04 名稱空間和做用域.py', '__cached__': None, 'chi': <function chi at 0x0000026EB5CF1E18>} ''' # print(locals()) # 全局 # print(globals()) # 全局
3.函數的互相調用和函數的嵌套
(1)函數的互相調用
def func1(): print("我是神器的func1") def func2(): func1() print("我是神器的func2") def func3(): print("我是神器的func3") # func5() def func4(): func3() print("我是神器的func4") def func5(): func2() func3() print("我是神器的func5") def func6(): func5() print("我是神器的func6") func3() func1() func6()
結果:面試
''' 結果: 我是神器的func1 我是神器的func2 我是神器的func3 我是神器的func5 我是神器的func6 我是神器的func3 我是神器的func1 '''
(2)函數的嵌套
(2-1)
def outer(): def inner(): print("個人天哪") print("還能夠這樣寫???") inner() outer() ''' 結果: 還能夠這樣寫??? 個人天哪 ''' # inner() # 在全局不能找到局部的內容,因此不能直接寫在外邊
(2-2)
def func1(): print("1") def func2(): print("2") def func3(): print("3") print("4") func3() print(5) print("6") func2() print("7") func1()
結果:數據結構
1 6 2 4 3 5 7
4.nonlocal&global
(1)
global是在內部修改全局
全局變量通常是不能隨意的修改的
a = 10 def func(): # 慎用. global a # 重點記憶:global 表示從全局把一個變量引入到局部, 後面使用的a都是全局變量 a += 10 # ?? a = a + 10 # 如今的a是全局的, 你如今視圖改全局變量 print("裏面的打印",a) func() print("外面的打印", a) ''' 結果: 裏面的打印 20 外面的打印 20 '''
(2)
nonlocal 在局部, 尋找離他最近的外層的一個變量
a = 50 def func1(): a = 10 # 局部,若是這裏沒有a=10,會報錯 def func2(): nonlocal a # 不找全局,只能找外層函數中的, global找全局 a += 10 # a = a + 10 python不讓這麼幹 print("func2", a) func2() print(a) func1() print(a)
結果:
func2 20
20
50
(3)
#無論是多少層.globals都是找全局裏的
#全局變量通常是不能隨意的修改的
#注意:nonlocal不能找全局變量
# nonlocal 在局部,尋找離他最近的外層的一個變量
# 若是沒有nonlocal和global 查找的順序: 本身, 上一層, 上一層, 上一層
def func1(): a=10 #局部 def func2(): nonlocal a a=30 print('func2',a) func2() print(a) func1() ''' 結果: func2 30 30 '''
(4)真假難辨,這種題都能作出來,還有什麼題目不能作出來閉包
a = 1 def fun_1(): a = 2 def fun_2(): nonlocal a a = 3 def fun_3(): a = 4 print(a) print(a) fun_3() print(a) print(a) fun_2() print(a) print(a) fun_1() print(a)
結果:app
結果:
1
2
3
4
3
3
1
(5)摺疊調用
def login(): global flag uname = input("用戶名:") upwd = input("密碼:") if uname == "alex" and upwd == "123": flag = True else: flag = False def fatie(): if flag == True: print("能夠發帖") else: print("滾去登陸") login() fatie()
今日做業:ide
2,寫函數,接收n個數字,求這些參數數字的和。(動態傳參)
方法一: def digit_sum(*args): print(sum(args)) digit_sum(1,2,3,4,5) 方法二: def digit_sum(*args): sum=0 for i in args: sum+=i print(sum) digit_sum(1,2,3,4,5)
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 10 None
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): return kwargs x={'name':'alex'} y={'age':1000} b=a(**x,**y) print(b)
7, 下面代碼成立麼?若是不成立爲何報錯?怎麼解決?
7.1 a = 2 def wrapper(): print(a) wrapper() #正確 7.2 a = 2 def wrapper(): a += 1 print(a) wrapper() #錯誤,在賦值前引用全局變量a 修改後的程序 a = 2 def wrapper(): global a a += 1 print(a) wrapper() 7.3 def wrapper(): a = 1 def inner(): print(a) inner() wrapper() #正確 7.4 def wrapper(): a = 1 def inner(): a += 1 print(a) inner() wrapper() #錯誤,在賦值前引用全局變量a #修改後的結果 def wrapper(): a = 1 def inner(): nonlocal a a += 1 print(a) inner() wrapper()
8,寫函數,接收兩個數字參數,將較小的數字返回.
def func(a,b): if a>b: return b else: return a x=func(2,3) print(x)
9,寫函數,接收一個參數(此參數類型必須是可迭代對象),
將可迭代對象的每一個元素以’_’相鏈接,造成新的字符串,並返回.
例如 傳入的可迭代對象爲[1,'老男孩','武sir']返回的結果爲’1_老男孩_武sir’
def func(x): s='' for i in x: 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
def cal(n): if n==0: return 1 return n * cal(n - 1) a=cal(3) print(a)
12寫函數,返回一個撲克牌列表,裏面有52項,每一項是一個元組
例如:[(‘紅心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
def puke(): a=['紅心','草花','梅花','黑桃'] b=[2,3,4,5,6,7,8,9,10,'J','Q','K','A'] lst=[] for i in b: for k in a: lst.append((k,i)) return lst a=puke() print(a)
13 有以下函數:
def wrapper():
def inner():
print(666)
wrapper()
你能夠任意添加代碼,用兩種或以上的方法,執行inner函數.
方法一 def wrapper(): def inner(): print(666) inner() wrapper() 方法二 def wrapper(): def inner(): print(666) return inner 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*j print('%s*%s=%s'%(i,j,r),' ',end='') print()