日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Day04:函数参数、对象、嵌套、闭包函数和装饰器

發布時間:2025/5/22 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Day04:函数参数、对象、嵌套、闭包函数和装饰器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上節課復習:
??? 1.什么是函數
??????? 函數就是具備某一功能的工具
??? 2.為何用函數
??????? 1.程序的組織結構和可讀性
??????? 2.減少代碼冗余
??????? 3.擴展性強
??? 3.如何用函數
??????? 函數分為兩大類:
??????????? 內置函數:len
??????????? 自定義函數: 1.有參 2.無參 3.空函數
??????? 語法:
??????????? def函數名(arg1,arg2)
??????????????? '''
??????????????? 注釋
??????????????? '''
??????????????? code1
??????????????? code2
??????????????? return 返回值
??????? 調用函數: 函數名(1,2,3)
??????? 函數必須遵循:先定義,后調用
??????? 定義階段:只檢測語法,與執行函數體代碼
??????? 調用階段:通過函數名找到函數,然后執行函數整體代碼
??????? 函數名:用來訪問函數的內存地址,加上括號用來執行函數
??????? 函數參數:是外調用者為函數體傳值的媒介
??????? 函數體代碼:是函數功能的具體實現
??????? 函數返回值是函數體執行的成果,不寫return默認返回None
??????????? 1.返回值沒有類型限制
??????????? 2.返回值沒有個數限制
??????????????? 無return,默認返回None
??????????????? return值1:返回1
??????????????? return值1,2,3,:返回值(1,2,3)
??????????? return注意點:是函數結束標志,函數體內可以有多個return,但是只要執行一次return,即代表函數結束

今日內容:
1.函數參數的使用
2.函數對象
3.函數嵌套
4.名稱空間與作用域
5.閉包函數(2+3+4)
6.裝飾器 一.函數參數的類型:
? 1.形參與實參
??? 形參:定義函數時,括號內指定的參數,本質就是調用名
??? 實參:調用函數時,括號內傳入的值
??? 只有在調用函數時才會在函數體內發生實參(值)與形參(變量名)的綁定關系
??? 該綁定關系只在調用函數時臨時生效,在調用函數結束時解除綁定 1 def foo(x,y): #括號內x,y 為形參 2 print(x) 3 print(y) 4 foo(1,2) # 括號內1,2為實參

輸出:

1
2

? 2.位置參數:
??? 位置形參:在定義函數時,從左往右的順序依次定義形參稱之為位置形參
??????? 注意:1.但凡是按照位置定義的形參,在調用函數時必須為其傳值,多一個少一個都不行
??? 位置實參:在調用函數時,從左往右的順序依次傳入值稱之為位置實參
??????? 注意:1.在傳值時按照順序與形參一一對應

1 def foo(x,y,z): #括號內x,y,z 為形參 2 print(x) 3 print(y) 4 foo(1,2) # 括號內1,2為實參

輸出:

---------------------------------------------------------------------------
TypeError???????????????????????????????? Traceback (most recent call last)
<ipython-input-3-b10bbf76aa4f> in <module>()
2???? print(x)
3???? print(y)
----> 4 foo(1,2) # 括號內1,2為實參

TypeError: foo() missing 1 required positional argument: 'z'

?3.關鍵字實參:
??? 在調用函數時,按照key=value的形式定義的實參,稱之為關鍵字實參
??? 注意:1.在傳值時可以完全打亂順序,但仍然能指名道姓地指定參數的傳值
???????? 2.可以在調用函數時,混用位置實參與關鍵字實參,但是位置實參必須在關鍵字實參的左邊,并且不能為某個形參重復性傳值
???????

1 def foo(x,y): #括號內x,y為形參 2 print(x) 3 print(y) 4 foo(y=3,x=2) # 指定關鍵字實參,可打亂順序

輸出:

2

3

4.默認參數:
??????? 在定義函數時,就已經為某些參數綁定值,稱之為默認參數
??????? 注意:
??????????? 1.在定義階段就已經有值,意味在調用階段可以不用為其傳值
??????????? 2.默認形參必須放到位置形參的后面
??????????? 3.默認形參的值只在定義階段生效一次
??????????? 4.默認形參的值通常應該是不可變類型

1 def foo(x,y,z=3): 2 print(x) 3 print(y) 4 print(z) 5 6 foo(1,2)

輸出:

1

2

3

? ? 歸納對比:默認形參vs位置形參:
??????? 默認形參:大多數情況值不變
??????? 位置形參:大多數情況值都是不一樣的

1 m=10 2 def foo(x,y,z=m): 3 print('x:%s' %x) 4 print('y:%s' %y) 5 print('z:%s' %z) 6 7 m=1111111 8 foo(1,2)

輸出:

x:1
y:2
z:10

1 def foo(name,hobby,l=[]): 2 l.append(hobby) 3 print('%s 的愛好是 %s' % (name,l)) 4 5 foo('andy','read') 6 foo('tom','run') 7 foo('alex','sing')

輸出:

andy 的愛好是 ['read']
tom 的愛好是 ['read', 'run']
alex 的愛好是 ['read', 'run', 'sing']

1 def foo(name,hobby,l=None): 2 if l is None: 3 l=[] 4 l.append(hobby) 5 print('%s 的愛好是 %s' % (name,l)) 6 l1=[] 7 foo('andy','read',l1) 8 foo('andy','music',l1) 9 foo('andy','run',l1) 10 l2=[] 11 foo('lily','run',l2) 12 l3=[] 13 foo('alex','sing',l3)

輸出:

andy 的愛好是 ['read']
andy 的愛好是 ['read', 'music']
andy 的愛好是 ['read', 'music', 'run']
lily 的愛好是 ['run']
alex 的愛好是 ['sing']

?5.可變長度的參數:
??????? 可變長度指的是在調用函數時,函數參數的個數可以不固定
??????? 然而實參終究是要為形參傳值的,針對兩種形式實參個數不固定,對應形參也必須要有兩種解決方案來分別處理溢出位置實參(*)與溢出的關鍵字實參(**)

1 #*會將溢出的位置實參存成元組,然后賦值給緊跟其后的變量名 2 #1.1 形參中帶* 3 def foo(x,y,*z): #*z=(3,4,5,6,7,8), 4 print(x) 5 print(y) 6 print(z) 7 foo(1,2,3,4,5,6,7,8)

輸出:

1
2
(3, 4, 5, 6, 7, 8)
1
2
('h', 'e', 'l', 'l', 'o')
h
e
('l', 'l', 'o')

1 #1.3 實參中帶*, 竅門:但凡碰到實參中帶*,都先將其打散成位置實參,然后再考慮傳值 2 def foo(x,y,z): 3 print(x,y,z) 4 l=['alex','tom','andy'] 5 foo(*l) #*后被打散

輸出:

alex tom andy

1 #1.1 形參中帶** 2 #**會將溢出的關鍵字實參存成字典,然后賦值給緊跟其后的變量名 3 4 def foo(x,y,m,n,**z): #**z={'a': 1, 'b': 2, 'c': 3}, 5 print(x) 6 print(y) 7 print(m) 8 print(n) 9 print(z) 10 foo(1,2,n=10,m=20,a=1,b=2,c=3)

輸出:

1
2
20
10
{'a': 1, 'b': 2, 'c': 3}

1 #1.2 形參中帶**,實參中帶** 2 #**會將溢出的關鍵字實參存成字典,然后賦值給緊跟其后的變量名 3 #竅門:但凡在實參中帶**,都將其打散稱關鍵字實參,然后考慮傳值 4 5 def foo(x,y,m,n,**z): #**z={'a': 1, 'b': 2, 'c': 3}, 6 print(x) 7 print(y) 8 print(m) 9 print(n) 10 print(z) 11 foo(1,2,n=10,m=20,**{'a':1,'b':2,'c':3})

輸出:

1
2
20
10
{'a': 1, 'b': 2, 'c': 3}

1 def foo(x,y,m,n,**z): #**z={'a': 1, 'b': 2, 'c': 3}, 2 print(x) 3 print(y) 4 print(m) 5 print(n) 6 print(z) 7 foo(1,n=10,m=20,**{'a':1,'b':2,'c':3,'y':111})

輸出:

1
111
20
10
{'a': 1, 'b': 2, 'c': 3}

1 #1.3 實參中帶** 2 def foo(x,y,z): #**z={'a': 1, 'b': 2, 'c': 3}, 3 print(x) 4 print(y) 5 print(z) 6 foo(**{'x':1,'y':1,'z':2})

輸出:

1
1
2

1 #如果需要將外層的函數的參數格式原封不動地轉嫁給內部調用的函數,就需要用到下述方法: 2 def index(name,age,sex): 3 print('name:%s age:%s sex:%s' %(name,age,sex)) 4 5 def wrapper(*args,**kwargs): #args=(1,2,3),kwargs={'a': 10, 'b': 20, 'c': 30} 6 print(args,kwargs) 7 index(*args,**kwargs) #index(*(1,2,3),**{'a': 10, 'b': 20, 'c': 30} 8 #我們雖然調用的是wrapper函數,但是我們遵循的其實是index函數的參數規則 9 wrapper(1,2,3,a=10,b=20,c=30)

輸出:

(1, 2, 3) {'a': 10, 'b': 20, 'c': 30} --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-31-02b3f05d6305> in <module>() 5 print(args,kwargs) 6 index(*args,**kwargs) ----> 7 wrapper(1,2,3,a=10,b=20,c=30) <ipython-input-31-02b3f05d6305> in wrapper(*args, **kwargs) 4 def wrapper(*args,**kwargs): #args=(1,2,3),kwargs={'a': 10, 'b': 20, 'c': 30} 5 print(args,kwargs) ----> 6 index(*args,**kwargs) 7 wrapper(1,2,3,a=10,b=20,c=30) TypeError: index() got an unexpected keyword argument 'a' 1 #如果需要將外層的函數的參數格式原封不動地轉嫁給內部調用的函數,就需要用到下述方法: 2 def index(name,age,sex): 3 print('name:%s age:%s sex:%s' %(name,age,sex)) 4 5 def wrapper(*args,**kwargs): #args=(1,2,3),kwargs={'a': 10, 'b': 20, 'c': 30} 6 print(args,kwargs) 7 index(*args,**kwargs) #index(*(1,2,3),**{'a': 10, 'b': 20, 'c': 30} 8 #我們雖然調用的是wrapper函數,但是我們遵循的其實是index函數的參數規則 9 wrapper('andy',sex='male',age=18)

輸出:

('andy',) {'sex': 'male', 'age': 18}
name:andy age:18 sex:male

1 #命名關鍵字參數(了解):但凡在*后**之前定義的參數稱之為命名關鍵字參數 2 #注意點: 3 #在調用函數時,傳值的形式必須是key=value 4 def foo(x,y,*,m=1,n): 5 print(x,y,m,n) 6 foo(1,2,n=3,m=4)

輸出:

1 2 4 3

1 #函數是第一類對象,意味著函數可以當作變量去使用 2 #3.可以當作函數的返回值 3 def bar(): 4 return foo 5 f=bar() 1 #4.可以當作容器類型的元素 2 def f1(): 3 print('from f1') 4 def f2(): 5 print('from f2') 6 l=[f1,f2] 7 print(l) 8 l[1]()

輸出:

[<function f1 at 0x000001ED436887B8>, <function f2 at 0x000001ED43688620>]
from f2

1 def pay(): 2 print('pay function') 3 4 def withdraw(): 5 print('withdraw function') 6 7 def auth(): 8 print('auth function') 9 10 def shopping(): 11 print('shopping function') 12 13 def transfer(): 14 print('transfer function') 15 16 func_dic={ 17 '1':pay, 18 '2':withdraw, 19 '3':auth, 20 '4':shopping, 21 '5':transfer 22 } 23 while True: 24 print(""" 25 0 退出 26 1 支付 27 2 取款 28 3 認證 29 4 購物 30 5 轉賬 31 """) 32 choice=input('請輸入您要執行的操作:').strip() #choice='123' 33 if choice == '0':break 34 if choice not in func_dic: 35 print('輸入錯誤的指令,請重新輸入') 36 continue 37 38 func_dic[choice]() # 39 40 1 #函數的嵌套調用:在調用一個函數時,其內部代碼又調用其他函數 2 def bar(): 3 print('from bar') 4 def foo(): 5 print('from foo') 6 bar() 7 foo() 1 def mar2(x,y): 2 if x>y: 3 return x 4 else: 5 return y 6 def max4(a,b,c,d): 7 res1=max2(a,b) 8 res2=max2(res1,c) 9 res3=max2(res2,d) 10 return res3 11 print (max4(1,2,3,4))

1.名稱空間與作用域:namespaces
??? 名稱空間是存放名字與值綁定關系的地方
??? 要取到值必須通過名字才能找,而名字又在名稱空間中放著,所以在取值時需要先到名稱空間中找到名字自然就拿到值的內存地址了
2.名稱空間分為三種:
??? a.內置名稱空間:存放python解釋器自帶的名字,生命周期:在解釋器啟動時產生,關閉時回收
??? b.全局名稱空間:除了內置的與局部的之外的名字都屬于全局名稱空間,生命周期:在程序文件執行時就立刻產生,程序執行完畢后就回收
??? c.局部名稱空間:存放的時函數內部定義的名字,生命周期:在調用函數時臨時生效,在調用函數結束時立刻回收
???
??? 加載順序:內置名稱空間--》全局名稱空間--》局部名稱空間
??? 加載名稱空間的目的:為了將名字與值的綁定關系存放起來,而存的目的時為了取,也就是說,當我們在查找名字時,必然時在三者其一中查找
??? 查找順序:局部名稱空間--》全局名稱空間--》內置名稱空間
??? 基于當前所在位置往后查找

1 x=100 2 y=200 3 #強調,函數的形參名屬于局部名稱空間 4 def foo(x,y): 5 print(x,y) 6 foo(1,2) 1 def f1(): 2 x=1 3 def f2(): 4 print('from f2') 5 f1()

? 4.作用域
?????? 作用域指的是作用范圍
?????? 分為:
?????? 全局作用范圍:包含內置名稱空間與全局名稱空間中的名字
????????????? 特點:全局有效
?????? 局部作用范圍:包含的局部名稱空間的名字
????????????? 特點:局部有效,臨時存活

1 x=11111 2 def foo(): 3 y=2 4 print(globals()) #返回的是全局作用域中的名字 5 print(dir(globals)['__builtins__']) #返回的是全局作用域中的內置名稱空間的名字 6 print(locals() is globals()) 7 foo() 1 #函數的作用域關系在函數定義階段就已經固定,與函數的調用位置無關 2 #即在調用函數時一定要跑到定義函數的位置尋找作用域關系 3 x=222# 3.找全局函數 4 def outter(): 5 x=111 #2.找外部函數 6 def inner(): 7 x=0 #1.先找函數體內部 8 print('from inner %s' %x) 9 return inner 10 x=333 #4.找全局函數 11 f=outter() #f=指向outter.locals.inner 12 print(f) 13 def foo(): 14 x=444 15 f() 16 foo()#返回000,只看定義函數的位置找 1 #global 名字聲明時來自于全局的 2 x=1 3 def func(): 4 global x 5 x=2 6 func() 7 print(x) 1 #nonlocal 聲明變量時來自于當前外層的,必須是在函數內 2 x=222 3 def f1(): 4 def f2(): 5 nonlocal x 6 x=0 7 f2() 8 print('f1-->',x) 9 f1() 10 print(x

函數的作用域關系是在函數定義階段就已經固定死的
#閉包函數
1.閉指的是-》定義在函數的內部函數
2.包指的是-》該內部函數包含對其外層作用域名字的引用
閉包函數通常需要結合函數對象的概念,將閉包函數返回到外部使用

1 def outter(): 2 x=100 3 def inner(): 4 print(x) 5 return inner() 6 f=outter() 7 #x=200 8 #f() 9 10 def foo(): 11 x=300 12 def bar(): 13 x=400 14 bar() 15 foo() 1 x=1 2 y=1 3 def outer(x,y): 4 def sum(): 5 res=x+y 6 return res 7 return sum 8 f=outer(1,2) 9 f() 1 #閉包函數范例 2 import requests 3 def outter(url): 4 def get(): 5 response=requests.get(url) 6 print(len(response.text)) 7 return get 8 jd=outter('https://www.jd.com') 9 jd() 10 baidu=outter('https://www.baidu.com') 11 baidu()

裝飾器:
??? 裝飾指的是為被裝飾對象添加新的功能
??? 器指的是工具
??? 裝飾器本身可以任意可調用的對象,被裝飾的對象也可以是任意可調用的對象
??? 目標:
??????? 寫一個函數用來為另一個函數添加新功能,需要遵循開放封閉原則(對修改時封閉的,對擴展時封閉的)
??????? 1.不修改被裝飾對象的源代碼
??????? 2.不修改被裝飾對象的調用方式

1 import time 2 def index(): 3 time.sleep(3) 4 print('welcome to index page') 5 def home(name): 6 time.sleep(3) 7 print('welcome to index page %s' %name) 8 def outer(func): #func=最原始的index 9 def timer(*args,**kwargs): 10 start=time.time() 11 func(*args,**kwargs) #最原始的index() 12 stop=time.time() 13 print('run time is %s' %(stop-start)) 14 return timer 15 #f=outer(index) 16 #f() 17 index=outer(index) 18 home=outer(home) 19 index() 20 home('alex') 1 #裝飾器的語法糖:在被裝飾對象正上方單獨一行寫上@裝飾器名字 2 import time 3 def index(): 4 time.sleep(3) 5 print('welcome to index page') 6 def home(name): 7 time.sleep(3) 8 print('welcome to index page %s' %name) 9 def timer(func): #func=最原始的index 10 def wrapper(*args,**kwargs): 11 start=time.time() 12 res=func(*args,**kwargs) #最原始的index() 13 stop=time.time() 14 print('run time is %s' %(stop-start)) 15 return res 16 return wrapper 17 #f=outer(index) 18 #f() 19 res=index() 20 print(res)

?

?

?

轉載于:https://www.cnblogs.com/dingchuan/p/9326014.html

總結

以上是生活随笔為你收集整理的Day04:函数参数、对象、嵌套、闭包函数和装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。