面試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之Bilibili自動更新郵件提醒並任務欄圖標
TAG:Python |