2025年P(guān)ython二級考試模擬試卷 閉包與裝飾器_第1頁
2025年P(guān)ython二級考試模擬試卷 閉包與裝飾器_第2頁
2025年P(guān)ython二級考試模擬試卷 閉包與裝飾器_第3頁
2025年P(guān)ython二級考試模擬試卷 閉包與裝飾器_第4頁
2025年P(guān)ython二級考試模擬試卷 閉包與裝飾器_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

2025年P(guān)ython二級考試模擬試卷閉包與裝飾器考試時(shí)間:______分鐘總分:______分姓名:______一、選擇題1.下列關(guān)于閉包的描述中,正確的是()。A.閉包是指一個(gè)函數(shù)內(nèi)部定義的函數(shù),該內(nèi)部函數(shù)可以訪問外部函數(shù)的局部變量。B.閉包是Python中一種特殊的類,用于封裝數(shù)據(jù)。C.閉包會阻止外部變量在函數(shù)執(zhí)行完畢后被垃圾回收。D.閉包只能訪問外部函數(shù)的全局變量。2.函數(shù)`outer`定義如下:```pythondefouter(x):definner(y):returnx+yreturninner```執(zhí)行`inner_func=outer(10)`后,`inner_func`是一個(gè)函數(shù),執(zhí)行`inner_func(5)`的結(jié)果是()。A.10B.15C.5D.拋出異常3.裝飾器的基本原理是()。A.重寫被裝飾函數(shù)的代碼。B.返回一個(gè)新的函數(shù)對象,該對象通常會對被裝飾函數(shù)的行為進(jìn)行修改或增強(qiáng)。C.刪除被裝飾函數(shù)。D.將被裝飾函數(shù)的代碼轉(zhuǎn)換成匯編語言。4.下列關(guān)于Python裝飾器`@decorator`語法的說法中,正確的是()。A.`@decorator`是一個(gè)函數(shù)調(diào)用,它接收被裝飾函數(shù)作為參數(shù)。B.`@decorator`語法糖會修改函數(shù)的`__doc__`屬性,但不會改變函數(shù)本身。C.使用`@decorator`裝飾函數(shù)`f`后,`f`的原有定義被覆蓋。D.裝飾器必須定義在函數(shù)定義語句的后面。5.以下裝飾器能夠?qū)崿F(xiàn)函數(shù)執(zhí)行計(jì)時(shí)功能的是()。A.```pythondeftimer(func):defwrapper(*args,kwargs):returnfunc(*args,kwargs)returnwrapper```B.```pythondeftimer(func):defwrapper(*args,kwargs):print("Start")result=func(*args,kwargs)print("End")returnresultreturnwrapper```C.```pythondeftimer(func):defwrapper(*args,kwargs):importtimestart=time.time()result=func(*args,kwargs)end=time.time()print(f"Executiontime:{end-start}seconds")returnresultreturnwrapper```D.```pythondeftimer(func):defwrapper(*args,kwargs):result=func(*args,kwargs)importtimeprint(f"Executiontime:{time.time()}seconds")returnresultreturnwrapper```6.考慮以下代碼:```pythondefdeco(a):defdecorator(func):defwrapper(*args,kwargs):print(f"Decoratorreceived:{a}")result=func(*args,kwargs)returnresultreturnwrapperreturndecorator@deco(10)deffoo(x):returnx*2```執(zhí)行`foo(5)`后,控制臺輸出的內(nèi)容是()。A.10B.20C.Decoratorreceived:10D.Decoratorreceived:57.以下關(guān)于帶參數(shù)裝飾器的說法中,正確的是()。A.帶參數(shù)裝飾器不能修改被裝飾函數(shù)的行為。B.帶參數(shù)裝飾器需要一個(gè)額外的內(nèi)部函數(shù)來接收裝飾器的參數(shù)。C.帶參數(shù)裝飾器可以直接接收被裝飾函數(shù)作為參數(shù)。D.帶參數(shù)裝飾器在語法上與普通裝飾器完全不同。8.以下代碼中,能夠正確實(shí)現(xiàn)日志記錄功能的裝飾器是()。```pythondeflog(func):defwrapper(*args,kwargs):#記錄函數(shù)調(diào)用前信息print(f"Callingfunction:{func.__name__}withargs{args}andkwargs{kwargs}")result=func(*args,kwargs)#記錄函數(shù)調(diào)用后信息print(f"Finishedfunction:{func.__name__}")returnresultreturnwrapper```A.代碼完全正確。B.缺少記錄返回值的語句。C.缺少記錄參數(shù)類型的語句。D.`print`函數(shù)的使用會導(dǎo)致日志信息混入標(biāo)準(zhǔn)輸出,不夠優(yōu)雅。9.以下關(guān)于多層裝飾器的說法中,正確的是()。A.裝飾器的執(zhí)行順序是從外到內(nèi)。B.被多層裝飾的函數(shù),其`__name__`屬性最終由最內(nèi)層的裝飾器決定。C.裝飾器之間可以相互傳遞參數(shù)。D.多層裝飾器可能會改變函數(shù)的參數(shù)列表。10.裝飾器`@once`用于確保被裝飾的函數(shù)在程序運(yùn)行期間只被調(diào)用一次,以下實(shí)現(xiàn)方案中,正確的是()。A.```pythondefonce(func):defwrapper(*args,kwargs):ifwrapper_called:returnwrapper_called=Truereturnfunc(*args,kwargs)returnwrapper```B.```pythondefonce(func):called=Falsedefwrapper(*args,kwargs):nonlocalcalledifcalled:returncalled=Truereturnfunc(*args,kwargs)returnwrapper```C.上述A和B方案都能實(shí)現(xiàn),但B更優(yōu)。D.上述A和B方案都存在全局變量泄漏的問題,應(yīng)使用類來實(shí)現(xiàn)。二、代碼閱讀題1.閱讀以下代碼:```pythondefmake_counter():count=0defcounter():nonlocalcountcount+=1returncountreturncounterinc=make_counter()inc1=make_counter()print(inc())#輸出?print(inc1())#輸出?print(inc())#輸出?```2.閱讀以下代碼:```pythondefuppercase(func):defwrapper(*args,kwargs):result=func(*args,kwargs)returnresult.upper()returnwrapper@uppercasedefgreet(name):returnf"hello,{name}"```3.閱讀以下代碼:```pythondefdebug(func):defwrapper(*args,kwargs):args_repr=[repr(a)forainargs]kwargs_repr=[f"{k}={v!r}"fork,vinkwargs.items()]signature=",".join(args_repr+kwargs_repr)print(f"Calling{func.__name__}({signature})")result=func(*args,kwargs)print(f"{func.__name__}returned{result!r}")returnresultreturnwrapper@debugdefadd(a,b):returna+b```4.閱讀以下代碼:```pythondefmemoize(func):cache={}defwrapper(*args):ifargsincache:returncache[args]result=func(*args)cache[args]=resultreturnresultreturnwrapper@memoizedeffib(n):ifn<2:returnnreturnfib(n-1)+fib(n-2)```三、代碼編寫題1.編寫一個(gè)裝飾器`@timeit`,它能夠打印出被裝飾函數(shù)的執(zhí)行時(shí)間(提示:使用`time.time()`)。2.編寫一個(gè)裝飾器`@validate`,它接受一個(gè)參數(shù)`expected_type`,用于驗(yàn)證被裝飾函數(shù)的返回值類型是否為`expected_type`。如果類型不匹配,則拋出`TypeError`。例如:```python@validate(str)defget_name():return"Alice"@validate(int)defget_age():return30```3.編寫一個(gè)裝飾器`@cache_result`,它使用一個(gè)字典來緩存被裝飾函數(shù)的返回值,基于函數(shù)的參數(shù)。如果相同參數(shù)的函數(shù)已被調(diào)用,則直接返回緩存的結(jié)果,否則執(zhí)行函數(shù)并將結(jié)果存入緩存。4.編寫一個(gè)閉包函數(shù)`make_power(base)`,它接受一個(gè)參數(shù)`base`,并返回一個(gè)函數(shù)。返回的函數(shù)接受一個(gè)參數(shù)`exponent`,并計(jì)算`base`的`exponent`次方。例如:```pythonpower_of_two=make_power(2)print(power_of_two(3))#輸出8power_of_three=make_power(3)print(power_of_three(2))#輸出9```試卷答案一、選擇題1.A解析思路:閉包的核心特征是內(nèi)部函數(shù)可以訪問并記住其外部函數(shù)創(chuàng)建時(shí)的局部變量,即使外部函數(shù)已經(jīng)執(zhí)行完畢。選項(xiàng)A準(zhǔn)確描述了這一點(diǎn)。選項(xiàng)B錯(cuò)誤,閉包是函數(shù),不是類。選項(xiàng)C錯(cuò)誤,閉包本身不阻止外部變量回收,只是內(nèi)部函數(shù)持有引用。選項(xiàng)D錯(cuò)誤,內(nèi)部函數(shù)可以訪問外部函數(shù)的局部和全局變量。2.B解析思路:`outer(10)`執(zhí)行后,返回了內(nèi)部函數(shù)`inner`的引用賦給`inner_func`。`inner`函數(shù)記住了其外部函數(shù)`outer`的局部變量`x`的值10。執(zhí)行`inner_func(5)`時(shí),`inner`函數(shù)接收`5`作為`y`的參數(shù),內(nèi)部邏輯`x+y`變?yōu)閌10+5`,結(jié)果為15。選項(xiàng)B正確。3.B解析思路:裝飾器本質(zhì)上是一個(gè)接受函數(shù)作為參數(shù)的函數(shù),它返回一個(gè)新的函數(shù)對象。這個(gè)新函數(shù)通常會修改或增強(qiáng)原函數(shù)的行為(例如添加日志、計(jì)時(shí)、權(quán)限檢查等)。選項(xiàng)B準(zhǔn)確描述了裝飾器的核心工作方式。選項(xiàng)A錯(cuò)誤,裝飾器通常不重寫原函數(shù)代碼。選項(xiàng)C錯(cuò)誤,裝飾器通常不刪除原函數(shù)。選項(xiàng)D錯(cuò)誤,裝飾器操作的是函數(shù)對象,不涉及代碼轉(zhuǎn)換。4.A解析思路:`@decorator`語法糖等價(jià)于在函數(shù)`f`定義上方添加一行`f=decorator(f)`。即裝飾器`decorator`接收函數(shù)`f`作為參數(shù),并返回一個(gè)新的函數(shù)對象,然后這個(gè)新對象被賦值給原來的函數(shù)名`f`。選項(xiàng)A正確描述了這一點(diǎn)。選項(xiàng)B錯(cuò)誤,雖然`__doc__`可能被修改,但本質(zhì)是返回值覆蓋。選項(xiàng)C錯(cuò)誤,原函數(shù)定義并未消失,但名稱指向了新函數(shù)。選項(xiàng)D錯(cuò)誤,裝飾器可以定義在任何位置,只要在函數(shù)定義之前。5.C解析思路:計(jì)時(shí)功能需要獲取函數(shù)執(zhí)行前后的時(shí)間差。選項(xiàng)C的代碼定義了一個(gè)裝飾器`timer`,其內(nèi)部`wrapper`函數(shù)在執(zhí)行原函數(shù)`func`前后分別調(diào)用`time.time()`獲取當(dāng)前時(shí)間,計(jì)算差值并打印,然后返回原函數(shù)的執(zhí)行結(jié)果。選項(xiàng)A缺少打印語句。選項(xiàng)B只打印了開始和結(jié)束的提示,沒有計(jì)算時(shí)間。選項(xiàng)D在函數(shù)返回后才打印時(shí)間,但打印的是時(shí)間戳本身,不夠直觀。6.C解析思路:裝飾器`deco`接受一個(gè)參數(shù)`a`(值為10)。然后定義了內(nèi)部裝飾器`decorator`,它接受函數(shù)`func`。內(nèi)部`wrapper`函數(shù)在執(zhí)行`func`前打印了傳入的`a`值(10)。`@deco(10)`裝飾了`foo`函數(shù),所以`func`是`foo`。執(zhí)行`foo(5)`時(shí),`wrapper`函數(shù)會打印`Decoratorreceived:10`,然后執(zhí)行`foo`,`foo`返回`5*2`即10。最終控制臺輸出的是打印語句和`foo`的返回值,但題目只問打印內(nèi)容,所以是C。7.B解析思路:帶參數(shù)裝飾器通常需要一個(gè)額外的內(nèi)部函數(shù)來處理裝飾器的參數(shù),然后返回一個(gè)裝飾器(通常是`wrapper`函數(shù))。這個(gè)`wrapper`函數(shù)會接收被裝飾的函數(shù)作為參數(shù)。選項(xiàng)B描述了這種常見的實(shí)現(xiàn)模式。選項(xiàng)A錯(cuò)誤,帶參數(shù)裝飾器可以修改函數(shù)行為。選項(xiàng)C錯(cuò)誤,裝飾器本身接收的是函數(shù),參數(shù)是在外部傳入裝飾器函數(shù)內(nèi)部的。選項(xiàng)D錯(cuò)誤,帶參數(shù)裝飾器是Python裝飾器的一種變體,語法結(jié)構(gòu)相似。8.A解析思路:代碼實(shí)現(xiàn)了日志記錄功能。它打印了調(diào)用前的函數(shù)名、參數(shù)和關(guān)鍵字參數(shù),執(zhí)行原函數(shù),然后打印了調(diào)用后的函數(shù)名。這符合日志記錄的基本需求。選項(xiàng)B、C、D提出的改進(jìn)或指出的問題在此基本功能實(shí)現(xiàn)中并非錯(cuò)誤,但原代碼本身是正確的。9.B解析思路:多層裝飾器的執(zhí)行順序是從最內(nèi)層向外層執(zhí)行。例如,`@decB@decAf`等價(jià)于`f=decA(decB(f))`。因此,函數(shù)`f`最終獲得的屬性(如`__name__`)是由最內(nèi)層的裝飾器`decB`決定的(如果它修改了的話)。選項(xiàng)A錯(cuò)誤。選項(xiàng)C和D描述的情況通常不會發(fā)生。10.B解析思路:方案B使用了`nonlocal`關(guān)鍵字聲明變量`called`,使其在嵌套函數(shù)`wrapper`中可讀寫。`wrapper`函數(shù)在每次被調(diào)用時(shí)檢查`called`,如果為`True`則返回,否則設(shè)置為`True`并執(zhí)行原函數(shù)。這確保了`called`狀態(tài)在函數(shù)調(diào)用鏈中保持正確,并且是閉包機(jī)制(通過`nonlocal`)的應(yīng)用。方案A的問題在于`wrapper_called`是在`wrapper`函數(shù)外部定義的,它不是`wrapper`函數(shù)的封閉環(huán)境的一部分,導(dǎo)致內(nèi)部`wrapper`無法訪問或修改它,相當(dāng)于一個(gè)全局變量。方案D雖然提到了類,但題目要求編寫裝飾器,且方案B本身就是有效的閉包實(shí)現(xiàn)。二、代碼閱讀題1.15,1,16解析思路:`make_counter`返回的是內(nèi)部函數(shù)`counter`。每次調(diào)用`counter`時(shí),都會使用`nonlocal`關(guān)鍵字修改外部作用域中`make_counter`創(chuàng)建時(shí)`count`的值。`inc`和`inc1`是兩個(gè)獨(dú)立的`counter`函數(shù)的實(shí)例,它們各自擁有獨(dú)立的`count`變量。第一次調(diào)用`inc()`時(shí),`count`從0變?yōu)?,輸出1。第二次調(diào)用`inc()`時(shí),`count`從1變?yōu)?,輸出2。然后調(diào)用`inc1()`,其`count`初始為0,變?yōu)?,輸出1。最后再次調(diào)用`inc()`,其`count`從2變?yōu)?,輸出3。注意:題目輸出描述為`?`,根據(jù)代碼邏輯推斷應(yīng)為`15,1,16`,但實(shí)際執(zhí)行結(jié)果如上分析。這里假設(shè)題目描述或輸出占位符有誤,實(shí)際邏輯如上。2.HELLO,{NAME}解析思路:`uppercase`裝飾器返回一個(gè)`wrapper`函數(shù),該函數(shù)執(zhí)行原函數(shù)`greet`并將返回結(jié)果強(qiáng)制轉(zhuǎn)為大寫。`@uppercase`裝飾了`greet`函數(shù)。執(zhí)行`greet("name")`時(shí),`wrapper`函數(shù)接收`name`參數(shù),調(diào)用`greet("name")`得到`"hello,name"`,然后將其轉(zhuǎn)為大寫得到`"HELLO,NAME"`并返回。所以最終結(jié)果是`HELLO,NAME`。3.Callingadd(2,3)5Finishedadd(2,3)Callingadd(2,3)5Finishedadd(2,3)Callingadd(2,3)5Finishedadd(2,3)解析思路:`debug`裝飾器返回一個(gè)`wrapper`函數(shù)。執(zhí)行`@debugadd(2,3)`時(shí),實(shí)際執(zhí)行的是`wrapper(2,3)`。*第一次:打印調(diào)用信息`Callingadd('2','3')`(參數(shù)被`repr`處理)。執(zhí)行`add(2,3)`,返回5。打印返回信息`addreturned5`。返回5。*第二次:再次調(diào)用`wrapper(2,3)`。打印調(diào)用信息`Callingadd('2','3')`。執(zhí)行`add(2,3)`,返回5。打印返回信息`addreturned5`。返回5。*第三次:再次調(diào)用`wrapper(2,3)`。打印調(diào)用信息`Callingadd('2','3')`。執(zhí)行`add(2,3)`,返回5。打印返回信息`addreturned5`。返回5。控制臺輸出按順序?yàn)樯鲜鋈糠帧?.1,1,2解析思路:`memoize`裝飾器使用字典`cache`來緩存結(jié)果。`fib`函數(shù)計(jì)算斐波那契數(shù)列。*第一次計(jì)算`fib(1)`:參數(shù)`args`為`(1,)`。`1`不在`cache`中。執(zhí)行`fib(1)`,返回1。將`(1,)`和結(jié)果1存入`cache`。返回1。*第二次計(jì)算`fib(1)`:參數(shù)`args`為`(1,)`。`1`在`cache`中,返回緩存值1。*第三次計(jì)算`fib(2)`:參數(shù)`args`為`(2,)`。`2`不在`cache`中。執(zhí)行`fib(2)`,計(jì)算`fib(1)+fib(0)`。`fib(1)`需要查找緩存,返回1。`fib(0)`需要查找緩存,返回0。執(zhí)行`1+0`,結(jié)果為1。將`(2,)`和結(jié)果1存入`cache`。返回1。*第四次計(jì)算`fib(1)`:參數(shù)`args`為`(1,)`。`1`在`cache`中,返回緩存值1。*第五次計(jì)算`fib(2)`:參數(shù)`args`為`(2,)`。`2`在`cache`中,直接返回緩存值1。*第六次計(jì)算`fib(1)`:參數(shù)`args`為`(1,)`。`1`在`cache`中,返回緩存值1。*第七次計(jì)算`fib(2)`:參數(shù)`args`為`(2,)`。`2`在`cache`中,直接返回緩存值2。最終按順序調(diào)用`fib(1)`,`fib(1)`,`fib(2)`,輸出結(jié)果為1,1,2。三、代碼編寫題1.```pythonimporttimedeftimeit(func):defwrapper(*args,kwargs):start_time=time.time()result=func(*args,kwargs)end_time=time.time()print(f"Function{func.__name__}took{end_time-start_time:.6f}seconds.")returnresultreturnwrapper@timeitdefexample_function():time.sleep(1)@timeitdefadd(a,b):returna+b```解析思路:裝飾器`timeit`需要計(jì)算函數(shù)執(zhí)行時(shí)間。內(nèi)部`wrapper`函數(shù)在調(diào)用原函數(shù)前后分別獲取當(dāng)前時(shí)間(使用`time.time()`)。時(shí)間差即為執(zhí)行時(shí)間,使用`print`輸出。最后返回原函數(shù)的執(zhí)行結(jié)果。使用`{func.__name__}`獲取被裝飾函數(shù)的名稱,使用`{end_time-start_time:.6f}`格式化輸出時(shí)間差到小數(shù)點(diǎn)后6位。`wrapper`函數(shù)使用`*args,kwargs`接受任意參數(shù)和關(guān)鍵字參數(shù),確保能裝飾任何函數(shù)。2.```pythondefvalidate(expected_type):defdecorator(func):defwrapper(*args,kwargs):result=func(*args,kwargs)ifnotisinstance(result,expected_type):raiseTypeError(f"Expectedreturntype{expected_type},got{type(result)}")returnresultreturnwrapper@validate(str)defget_name():return"Alice"@validate(int)defget_age():return30#@validate(str)get_name()#正常工作#@validate(int)get_age()#正常工作#get_name()#輸出Alice#get_age()#輸出30#try:#@validate(str)#defget_age_str():#return25#get_age_str()#exceptTypeErrorase:#print(e)#輸出Expectedreturntype<class'int'>,got<class'str'>```解析思路:裝飾器`validate`接受一個(gè)參數(shù)`expected_type`。內(nèi)部`decorator`函數(shù)接收函數(shù)`func`。內(nèi)部`wrapper`函數(shù)執(zhí)行原函數(shù)`func`,獲取返回值`result`。使用`isinstance(result,expected_type)`檢查返回值類型是否與`expected_type`匹配。如果不匹配,拋出`TypeError`,錯(cuò)誤信息包含期望類型和實(shí)際類型。如果匹配,返回`result`。返回`wrapper`函數(shù)作為裝飾器的結(jié)果。3.```pythondefcache_result(func):cache={}defwrapper(*args,kwargs):#創(chuàng)建一個(gè)基于args和kwargs的緩存鍵,例如元組cache_key=args,frozenset(kwargs.items())ifcache_keyincache:print(f"Cachehitfor{func.__name__}withargs{args}kwargs{kwargs}")returncache[cache_key]else:result=func(*args,kwargs)cache[cache_key]=resultprint(f"Cachemissfor{func.__name__}withargs{args}kwargs{kwargs}")returnresultreturnwrapper@cache_resultdefexpensive_calculation(x,y):p

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論