巨蟒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)
分別傳遞給形參
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()
View Code

結果:數據結構

1
6
2
4
3
5
7
View Code

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
View Code
(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)
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 10
None
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):
    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()
相關文章
相關標籤/搜索