當前位置:
首頁 > 最新 > 面試Python如果你說出這幾招,讓你瞬間牛叉

面試Python如果你說出這幾招,讓你瞬間牛叉

菜鳥學Python的第147篇原創文章

閱讀本文大概需要3分鐘

菜鳥獨白

Python的類裡面有很多內置的函數,或者是特殊的函數平時我們不怎樣用,一般都是默認調用。但是在面試Python的時候如果你懂這些招數,可以說出這些用法,必定瞬間讓你的面試官眼前一亮,增分不少。這些算是Python進階的知識,對理解Python的精髓非常有好處!都是什麼招數呢,精選3個小例子,迅速提升功力!

1.什麼是__call__函數

1).這個是不是非常非常罕見,幾乎從來用不到這個內置的函數!錯了,其實我們在用類的幾乎時時在用.__call__可以讓類模擬函數的行為.如果一個對象提供了該方法,就可以像函數一樣使用它:

run in init

a: 1

Foo是一個類,類初始化的時候,調用init函數,並生成一個f對象實例

f("xin")

run in call

name: xin

運行f對象的時候會去調用__call__函數.這個語法其實非常有趣,算是把這個類型的對象當作函數來使用,相當於重載了括弧運算符。

2).__call__這個概念會涉及到類裝飾器

類裝飾器其實是一個非常複雜的概念,這裡我們看一個小例子來簡單的理解一下:

add(1,2)

run in init...

a+b: 3

add("hi"," python")

run in init...

a+b: hi python

這個稍微有一點複雜,我們設計一個decorator類,然後在add函數的時候用類裝飾器,這個時候add函數已經不是簡單的函數了,因為用了類裝飾器,搖身一變陞官了,而是add=decorator(add),add已經是嫁入豪門,add其實是decorator類的一個對象了.

也就是把add函數的地址傳入了decorator裡面的init函數,並且返回一下對象實例add.所以當你運行add(1,2)的時候就會調用__call__函數.

2.__new__和__init__的區別

前面有一篇文章(這8道Python面試題,你答不答的出來),__init__方法其實是初始化方法,真正的構造方法是__new__。__new__是類方法.

當時沒有舉例子,不太好理解,這裡我們看一個小例子,比如我們都知道tuple元組是不可變對象,如果我們想自己構造一個新的元組返回都是int,我們自定義一個IntTuple來繼承tuple,來深入理解一下__new__和__init__的秘密。

print (t)

self:(1, -1, "a"),seq:(1, -1, "a")

(1, -1, "a")

也就是說我們我們傳進去的seq[1,-1,"-a"],在__init__裡面是沒有地方可以更改的,那如何更改呢,這是時候__new__要上場了.

print (t)

self: (1, -1)

(1, -1)

init裡面無法動手腳,我們只能往前追蹤,看看它的上游new裡面是否可以動態的改變!類初始化的時候首先運行了__new__函數,傳入seq。

我們對seq進行過濾處理,只留一下int類型,然後__new__裡面return返回處了類的實例給__init__(),其實__init__裡面的self就是__new__返回的!

3.__set__,__get__,__delete__都是啥

1).這3個特殊的函數說實話我學Python的時候都沒有用過,後來在看一些進階的書的時候才發現它的妙用!

其實都是Python類裡面的描述符概念,描述符允許你自定義在引用一個對象屬性是應該完成的事情。這3個特殊的方法組合了Python裡面的描述法協議:

__set__:在設計屬性的時候被調用

__get__:在讀取屬性的時候被調用

__delete__:在刪除屬性的時候被調用

a=A()

a.x

In __get__

被__get__函數截獲,這個時候傳入的instance是a,而owner是他的類即為A

a.x=5

>>In __set__ 5

對x進行賦值的時候,其實就會被__set__捕獲,這個時候傳入的instance是a,而value為5

del a.x

>>In __del

對x進行刪除的時候,其實就會被__del__捕獲,這個時候傳入的instance是a

2).有同學說這個描述符有啥用啊

下面舉一個小例子,看看它的妙用,比如我們要設計一個類,我們希望它能想C,C++那樣對它們的實例屬性做類型檢查:

p=Person()

p.name="jack" #名字必須是str

p.age=18 #年齡必須是int

p=Person()

p.name="lily"

print ("name:",p.name)

name: lily

如果寫成

p.name=123

raise TypeError("expected an {}".format(self.your_type))

TypeError: expected an

Python裡面還有很多比較深奧的知識點,這些知識都是進階的內容。都說Python入門容易精通難,若想要深刻領悟Python之美,需要深入的挖掘和探究它的內在特性,要深入到語言內部去分析它的內在機制和奧秘!我在小密圈裡面說過Python有3大難點,我後面會寫文章一一介紹!

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

Python之Bilibili自動更新郵件提醒並任務欄圖標

TAG:Python |