国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

(三十三)補(bǔ)充Python經(jīng)典面試題(吸收高級(jí)編程特性)

這篇具有很好參考價(jià)值的文章主要介紹了(三十三)補(bǔ)充Python經(jīng)典面試題(吸收高級(jí)編程特性)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

第一題:

def func(a, b=[]): pass

一、上題講解:

這個(gè)函數(shù)定義有一個(gè)默認(rèn)參數(shù)b,它的默認(rèn)值是一個(gè)空列表[]。這道面試題涉及到Python中函數(shù)參數(shù)默認(rèn)值的一些重要概念和陷阱。

首先,當(dāng)你調(diào)用這個(gè)函數(shù)時(shí),如果不傳遞參數(shù)b的值,它將使用默認(rèn)的空列表[]。例如:

func(1)  # 這會(huì)將a設(shè)置為1,b設(shè)置為默認(rèn)的空列表[]

但是,這里有一個(gè)陷阱。默認(rèn)參數(shù)b(即空列表[])在函數(shù)定義時(shí)只會(huì)被創(chuàng)建一次,而不是每次函數(shù)調(diào)用時(shí)都會(huì)創(chuàng)建一個(gè)新的空列表。這就意味著,如果你在一個(gè)函數(shù)調(diào)用中修改了b的值,那么下一次調(diào)用該函數(shù)時(shí),b將保留上一次的修改。

例如:

func(1)  # a=1, b=[]
b.append(2)
func(3)  # a=3, b=[2]

在上面的例子中,我們首先調(diào)用了func(1),然后在b上執(zhí)行了append(2)操作,導(dǎo)致b變成了[2]。接下來,我們調(diào)用了func(3),此時(shí)a被設(shè)置為3,但b仍然是[2],而不是一個(gè)新的空列表[]。

這種行為可能會(huì)導(dǎo)致一些不直觀的問題和bug,因?yàn)槭褂谜呖赡芷谕看握{(diào)用函數(shù)時(shí)都會(huì)得到一個(gè)獨(dú)立的空列表。

為了避免這種問題,我們可以使用None作為默認(rèn)值,并在函數(shù)內(nèi)部檢查b是否為None,然后在需要時(shí)創(chuàng)建一個(gè)新的空列表。例如:

def func(a, b=None):
    if b is None:
        b = []
    # 現(xiàn)在每次函數(shù)調(diào)用都會(huì)得到一個(gè)新的空列表
    # 其他函數(shù)邏輯

這樣做可以確保每次調(diào)用函數(shù)時(shí)都會(huì)得到一個(gè)新的空列表,避免了默認(rèn)參數(shù)共享的問題。

二、是什么導(dǎo)致的上述問題:

這是因?yàn)樵赑ython中,默認(rèn)參數(shù)在函數(shù)定義時(shí)只會(huì)被創(chuàng)建一次,并且在函數(shù)的整個(gè)生命周期內(nèi)都會(huì)保留它們的狀態(tài)。這是為了提高函數(shù)的性能和效率。

當(dāng)你定義一個(gè)函數(shù)時(shí),Python會(huì)在函數(shù)的定義階段創(chuàng)建默認(rèn)參數(shù)的值,然后將這些值存儲(chǔ)在函數(shù)的代碼對(duì)象中。這意味著每次調(diào)用函數(shù)時(shí),不會(huì)重新創(chuàng)建默認(rèn)參數(shù)的新實(shí)例,而是會(huì)重用已經(jīng)存在的默認(rèn)參數(shù)。

這種行為有一些優(yōu)點(diǎn)和一些潛在的陷阱:

優(yōu)點(diǎn):

  1. 提高了函數(shù)的性能,因?yàn)椴恍枰看魏瘮?shù)調(diào)用都創(chuàng)建新的默認(rèn)參數(shù)對(duì)象。
  2. 可以實(shí)現(xiàn)一些有用的功能,例如在多次函數(shù)調(diào)用之間共享狀態(tài)。這可以在某些情況下很有用。

潛在的陷阱:

  1. 如果默認(rèn)參數(shù)是可變對(duì)象(如列表或字典),并且在函數(shù)內(nèi)部進(jìn)行了修改,那么這些修改會(huì)在后續(xù)函數(shù)調(diào)用中保留下來,可能導(dǎo)致不直觀的行為。
  2. 開發(fā)者需要謹(jǐn)慎處理默認(rèn)參數(shù),以避免意外共享狀態(tài)的問題。

要避免默認(rèn)參數(shù)共享狀態(tài)的問題,可以使用None作為默認(rèn)參數(shù)的值,并在函數(shù)內(nèi)部檢查并創(chuàng)建新的實(shí)例,如上解決的方法所示。

總之,Python的默認(rèn)參數(shù)在函數(shù)定義時(shí)只會(huì)被創(chuàng)建一次,這是出于性能和實(shí)現(xiàn)的考慮,但在使用可變對(duì)象作為默認(rèn)參數(shù)時(shí)需要特別小心,以避免不希望的副作用。

第二題:

val = [lambda: i + 1 for i in range(10)]

data = val[0]()
print(data)

這道面試題涉及到Python中的lambda函數(shù)和列表推導(dǎo)式,并且可能會(huì)引發(fā)一個(gè)常見的陷阱,即閉包與變量作用域的問題。

將上述代碼拆開來看:

def a():
    return i + 1


s = []
for i in range(10):
    s.append(a)

print(s[0]())

相信很多小伙伴看到上述拆開的代碼都已經(jīng)能理解本道面試題的精髓所在了。
但也請(qǐng)繼續(xù)看下原理,是否和你想的一樣~

講解原理:

首先,列表推導(dǎo)式 [lambda: i + 1 for i in range(10)] 創(chuàng)建了一個(gè)包含 10 個(gè) lambda 表達(dá)式的列表,每個(gè) lambda 表達(dá)式在調(diào)用時(shí)都會(huì)返回 i + 1 的值。**需要注意的是這里每個(gè) lambda 表達(dá)式都是一個(gè)閉包,它們“記住”了變量 i 的值。 然而,關(guān)鍵之處在于 lambda 表達(dá)式記住的是變量 i 而非 i 當(dāng)時(shí)的值。**由于列表推導(dǎo)式內(nèi)的 i 是在單個(gè)作用域內(nèi)循環(huán)的,因此當(dāng)列表推導(dǎo)式結(jié)束時(shí),i 的值將停留在最后一次循環(huán)的值,即 9。 之后的代碼 data = val[0]選擇列表中的第一個(gè) lambda 函數(shù)并調(diào)用它。因?yàn)樗械?lambda 閉包都是對(duì)同一個(gè) i 的引用,這時(shí) i 的值是循環(huán)結(jié)束時(shí)的值 9。因此,無論調(diào)用列表中的哪一個(gè) lambda 表達(dá)式,它都能返回 9 + 1,即 10。

這是因?yàn)椋?*在 Python 的 for 循環(huán)中,循環(huán)變量 i 會(huì)被綁定到列表推導(dǎo)式的外部作用域,而不是每次迭代都創(chuàng)建一個(gè)新的作用域。**所以,所有的 lambda 表達(dá)式都引用著同一個(gè) i 變量,而在循環(huán)結(jié)束時(shí),i 的值為 9。 要讓每個(gè) lambda 表達(dá)式保留它被定義時(shí)的 i 值,可以使用默認(rèn)參數(shù)來捕獲i的值,以確保每個(gè)lambda函數(shù)都捕獲到不同的值:

val = [lambda i=i: i + 1 for i in range(10)]

data = val[0]()
print(data)

上面修改后的代碼中,lambda i=i: i + 1 為每個(gè) lambda 函數(shù)創(chuàng)建了一個(gè)默認(rèn)參數(shù) i,它的值在定義 lambda 函數(shù)時(shí)就被確定下來了。這時(shí),val[0]會(huì)輸出 1,因?yàn)樗鼘⑹褂昧斜硗茖?dǎo)式中第一次迭代時(shí) i 的值,即 0,然后加 1。

第三題:

老生常談,請(qǐng)講一講迭代器,生成器,可迭代對(duì)象,裝飾器,并講一下它們各自的應(yīng)用場景。

首先,迭代器(Iterator)、生成器(Generator)、可迭代對(duì)象(Iterable)都與遍歷數(shù)據(jù)集合相關(guān),但各有特點(diǎn),所以放一起講:

1.1 迭代器(Iterators):

迭代器是遵循迭代器協(xié)議的對(duì)象,這意味著迭代器對(duì)象需要實(shí)現(xiàn)兩個(gè)方法:__iter__()__next__()。__iter__() 返回迭代器對(duì)象本身,而 __next__() 方法返回容器中的下一個(gè)元素。當(dāng)?shù)髦袥]有更多元素時(shí),__next__()應(yīng)該拋出一個(gè) StopIteration 異常。迭代器允許一個(gè)對(duì)象對(duì)一組數(shù)據(jù)進(jìn)行遍歷,但不需要此數(shù)據(jù)在內(nèi)存中完全展開。

  • Python的內(nèi)置容器類型:

    如列表、元組、字典等,都提供了迭代器。例如,當(dāng)你在列表上調(diào)用 __iter__()函數(shù)時(shí),會(huì)返回一個(gè)迭代器,該迭代器可以遍歷列表的所有元素。

  • 使用場景:

    當(dāng)需要訪問集合中的元素而不暴露底層表示時(shí);

    當(dāng)需要一個(gè)能夠記住遍歷位置的對(duì)象時(shí),以便在需要時(shí)能夠從同一位置繼續(xù)。

1.2 生成器(Generators):

生成器是一種特殊的迭代器,更容易編寫。**當(dāng)需要一次一個(gè)地按順序生成一個(gè)序列的值時(shí),使用生成器是非常有用的。**生成器函數(shù)使用 yield 語句,每次產(chǎn)生(yield)一個(gè)值,函數(shù)的狀態(tài)會(huì)被掛起,直到下一個(gè)值被請(qǐng)求時(shí)再恢復(fù)。 生成器表達(dá)式是另一種構(gòu)建生成器的方式,它看起來像列表推導(dǎo)式,但使用圓括號(hào)而不是方括號(hào)。

  • 使用場景:

    當(dāng)需要一個(gè)懶序列(lazy sequence),該序列按需計(jì)算元素而不是預(yù)先計(jì)算,并且不希望一次性加載所有元素到內(nèi)存中;

    當(dāng)處理的是流式數(shù)據(jù)或大數(shù)據(jù)集合,只需要一次處理一部分?jǐn)?shù)據(jù);

    當(dāng)需要一個(gè)函數(shù)來生成無窮序列下的元素。

1.3 可迭代對(duì)象(Iterables):

可迭代對(duì)象是實(shí)現(xiàn)了 __iter__() 方法的任何 Python 對(duì)象,__iter__() 需要返回一個(gè)迭代器。另外,可迭代對(duì)象也可以實(shí)現(xiàn) __getitem__() 方法,以便按照索引訪問元素。字符串、列表等 Python 標(biāo)準(zhǔn)類型都是可迭代的。

class Demo(object):
	def __iter__(self):
		return iter([1, 2, 3])


obj = Demo()
  • 使用場景:

    在使用 for 循環(huán)時(shí),你通常會(huì)迭代一個(gè)可迭代對(duì)象;

    當(dāng)需要一種方式可以一次訪問一組元素,而無需將它們?nèi)勘4嬖趦?nèi)存中;

    在使用 map()、filter()、sum()、min()、max() 等內(nèi)置函數(shù)時(shí),這些函數(shù)接受一個(gè)可迭代對(duì)象作為參數(shù)

1.4 總結(jié)一下:

在 Python 中,迭代器、生成器和可迭代對(duì)象是集合數(shù)據(jù)訪問的三個(gè)基本概念。迭代器提供了一種通用的遍歷集合數(shù)據(jù)的方法,而生成器提供了一種生成迭代數(shù)據(jù)的簡潔方式,可迭代對(duì)象則定義了可以生成迭代器的對(duì)象。它們的共同目的是為了在保持代碼簡潔的同時(shí),有效地處理數(shù)據(jù)集合,尤其是在數(shù)據(jù)量非常大或者是無限的情況下。 理解并掌握這些概念對(duì)于編寫高效和可讀性高的 Python 代碼非常重要。每個(gè)概念都在數(shù)據(jù)處理和控制流的抽象中扮演著關(guān)鍵角色,并廣泛應(yīng)用于數(shù)據(jù)分析領(lǐng)域、系統(tǒng)操作領(lǐng)域和網(wǎng)絡(luò)編程等領(lǐng)域。

2.0 裝飾器(Decorator):

裝飾器是Python中的一種高級(jí)編程特性,**它允許你在不修改原始函數(shù)代碼的情況下,動(dòng)態(tài)地增強(qiáng)或修改函數(shù)的行為。**裝飾器通常用于代碼重用、添加功能、修改函數(shù)的輸入/輸出等方面,它是Python函數(shù)式編程的一部分,非常強(qiáng)大和靈活。

  1. 函數(shù)裝飾器

    • 裝飾器本質(zhì)上是一個(gè)Python函數(shù),它接受一個(gè)函數(shù)作為參數(shù),并返回一個(gè)新的函數(shù)。
    • 裝飾器函數(shù)通常在函數(shù)定義之前使用@符號(hào)來裝飾目標(biāo)函數(shù)。
    • 裝飾器的主要作用是在不修改原函數(shù)代碼的情況下,為函數(shù)添加額外的功能或修改其行為。
  2. 裝飾器示例
    下面是一個(gè)簡單的裝飾器示例,它用于測量函數(shù)的執(zhí)行時(shí)間:

    import time
    
    
    def timing_decorator(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            print(f"{func.__name__} took {end_time - start_time} seconds to execute.")
            return result
    
        return wrapper
    
    
    @timing_decorator
    def my_function():
        # Some time-consuming task
        time.sleep(2)
    
    
    my_function()
    
    

    在這個(gè)示例中,timing_decorator裝飾器測量了my_function函數(shù)的執(zhí)行時(shí)間,而不需要修改my_function的源代碼。

  3. 多個(gè)裝飾器
    你可以為一個(gè)函數(shù)應(yīng)用多個(gè)裝飾器,它們按照從上到下的順序執(zhí)行。這允許你將不同的功能組合在一起,以增強(qiáng)函數(shù)的行為。

    @decorator1
    @decorator2
    def my_function():
        # ...
    
    # 等效于
    my_function = decorator1(decorator2(my_function))
    
  4. 內(nèi)置裝飾器
    Python提供了一些內(nèi)置裝飾器,如@staticmethod@classmethod,用于定義靜態(tài)方法和類方法。這些裝飾器可以用于類中的方法,以提供不同類型的方法調(diào)用。

    class MyClass:
        def __init__(self, value):
            self.value = value
    
        @staticmethod
        def static_method():
            print("This is a static method")
    
        @classmethod
        def class_method(cls):
            print("This is a class method")
    
    
    obj = MyClass(42)
    obj.static_method()
    obj.class_method()
    
    
  5. 自定義裝飾器
    你可以自己編寫裝飾器函數(shù),以滿足特定需求。通常,自定義裝飾器需要接受函數(shù)作為參數(shù),并返回一個(gè)包裝函數(shù)。裝飾器函數(shù)可以在包裝函數(shù)的前后執(zhí)行自定義邏輯。

裝飾器是Python中強(qiáng)大而靈活的工具,它們用于增強(qiáng)函數(shù)的功能、提供代碼重用和簡化代碼結(jié)構(gòu)。常見的裝飾器包括日志記錄、性能分析、權(quán)限驗(yàn)證、緩存等。理解和熟練使用裝飾器是成為高級(jí)Python開發(fā)人員的關(guān)鍵一步。文章來源地址http://www.zghlxwxcb.cn/news/detail-763463.html

到了這里,關(guān)于(三十三)補(bǔ)充Python經(jīng)典面試題(吸收高級(jí)編程特性)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【隨筆】Git 高級(jí)篇 -- 推送主分支 git rebase & git fetch(三十三)

    【隨筆】Git 高級(jí)篇 -- 推送主分支 git rebase & git fetch(三十三)

    ?? 所屬專欄:【Git】 ?? 作??者:我是夜闌的狗?? ?? 個(gè)人簡介:一個(gè)正在努力學(xué)技術(shù)的CV工程師,專注基礎(chǔ)和實(shí)戰(zhàn)分享 ,歡迎咨詢! ?? 歡迎大家:這里是CSDN,我總結(jié)知識(shí)的地方,喜歡的話請(qǐng)三連,有問題請(qǐng)私信 ?? ?? ?? 您的點(diǎn)贊、關(guān)注、收藏、評(píng)論,是對(duì)我最大

    2024年04月23日
    瀏覽(30)
  • 每日三個(gè)JAVA經(jīng)典面試題(四十三)

    在大數(shù)據(jù)環(huán)境下優(yōu)化Java性能涉及多個(gè)方面,包括調(diào)整JVM設(shè)置、代碼優(yōu)化和選擇合適的工具和框架。以下是一些具體的優(yōu)化建議: 調(diào)整JVM參數(shù) : 增加堆內(nèi)存 :通過調(diào)整 -Xms (堆起始大?。┖?-Xmx (堆最大大?。﹨?shù),為Java應(yīng)用程序提供足夠的內(nèi)存空間,以減少垃圾回收的頻

    2024年04月26日
    瀏覽(20)
  • Python工具箱系列(三十三)

    Python工具箱系列(三十三)

    Timescaledb 在物聯(lián)網(wǎng)時(shí)代,出現(xiàn)了大量以時(shí)間為中心海量產(chǎn)生的傳感器數(shù)據(jù),稱為時(shí)序數(shù)據(jù)。這類數(shù)據(jù)的特點(diǎn)是: 數(shù)據(jù)記錄總有一個(gè)時(shí)間戳。 數(shù)據(jù)幾乎總是追加,不更新也不刪除。 大量使用近期的數(shù)據(jù)。很少更新或者回填時(shí)間間隔的缺失數(shù)據(jù)。 與時(shí)間間隔頻率關(guān)系不大。但累

    2024年02月06日
    瀏覽(20)
  • 【跟小嘉學(xué) Rust 編程】三十三、Rust的Web開發(fā)框架之一: Actix-Web的基礎(chǔ)

    【跟小嘉學(xué) Rust 編程】三十三、Rust的Web開發(fā)框架之一: Actix-Web的基礎(chǔ)

    【跟小嘉學(xué) Rust 編程】一、Rust 編程基礎(chǔ) 【跟小嘉學(xué) Rust 編程】二、Rust 包管理工具使用 【跟小嘉學(xué) Rust 編程】三、Rust 的基本程序概念 【跟小嘉學(xué) Rust 編程】四、理解 Rust 的所有權(quán)概念 【跟小嘉學(xué) Rust 編程】五、使用結(jié)構(gòu)體關(guān)聯(lián)結(jié)構(gòu)化數(shù)據(jù) 【跟小嘉學(xué) Rust 編程】六、枚舉

    2024年02月04日
    瀏覽(29)
  • 突破編程_C++_面試(高級(jí)特性(1))

    線程( Thread )是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位,它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。一條線程指的是進(jìn)程中一個(gè)單一順序的控制流,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)。 線程是獨(dú)立調(diào)度和分派的基本單位,同一進(jìn)程中的多條

    2024年02月20日
    瀏覽(12)
  • 一個(gè)月學(xué)通Python(三十):Python并發(fā)編程(上)

    結(jié)合自身經(jīng)驗(yàn)和內(nèi)部資料總結(jié)的Python教程,每天3-5章,最短1個(gè)月就能全方位的完成Python的學(xué)習(xí)并進(jìn)行實(shí)戰(zhàn)開發(fā),學(xué)完了定能成為大佬!加油吧!卷起來! 全部文章請(qǐng)?jiān)L問專欄:《Python全棧教程(0基礎(chǔ))》 再推薦一下最近熱更的:《大廠測試高頻面試題詳解》 該專欄對(duì)近年

    2024年02月14日
    瀏覽(25)
  • python:并發(fā)編程(十三)

    本文將和大家一起探討python提供高級(jí)接口(進(jìn)程池、線程池)的并發(fā)編程,使用內(nèi)置基本庫concurrent.futures來實(shí)現(xiàn)并發(fā),先通過官方來簡單使用這個(gè)模塊。先打好基礎(chǔ),能夠有個(gè)基本的用法與認(rèn)知,后續(xù)文章,我們?cè)龠M(jìn)行詳細(xì)使用。為什么說是concurrent.futures,而不是concurrent呢?

    2024年02月09日
    瀏覽(21)
  • python:并發(fā)編程(二十三)

    python:并發(fā)編程(二十三)

    本文將和大家一起探討python并發(fā)編程的實(shí)際項(xiàng)目:win圖形界面應(yīng)用 (篇五,共八篇) ,系列文章將會(huì)從零開始構(gòu)建項(xiàng)目,并逐漸完善項(xiàng)目,最終將項(xiàng)目打造成適用于高并發(fā)場景的應(yīng)用。 本文為python并發(fā)編程的第二十三篇,上一篇文章地址如下: python:并發(fā)編程(二十二)

    2024年02月11日
    瀏覽(17)
  • 第三十九天 Java基礎(chǔ)學(xué)習(xí)(三十三)

    一、Servlet Java類。由Servlet容器(Tomcat)進(jìn)行編譯-.class -運(yùn)行 產(chǎn)生響應(yīng)結(jié)果返回給客戶端瀏覽器。 生命周期:(方法調(diào)用流程) init:初始化方法。在第一次訪問servlet時(shí)被調(diào)用一次。 service:完成servlet所做功能。每次訪問servlet時(shí)都會(huì)被調(diào)用。 doGet0:只有g(shù)et請(qǐng)求。才能訪問。 doPos

    2024年02月15日
    瀏覽(50)
  • 第十三單元 補(bǔ)充知識(shí)

    第十三單元 補(bǔ)充知識(shí)

    泛指某種類型。 1、使用參數(shù)形式定義 2、使用時(shí)傳入具體類型 3、編譯時(shí)檢查類型安全 4、邏輯上是多個(gè)不同類型 泛型與非泛型之間的區(qū)別 性能高:可以避免裝箱和拆箱操作 類型安全 :在進(jìn)行類型轉(zhuǎn)換的時(shí)候不會(huì)拋出異常 代碼重用:定義一次,用許多種不同類型實(shí)例化 代

    2024年02月06日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包