Python裡面這些點,據說80%的新手都會一臉懵逼

qq1622479435發表於2018-10-14

Python雖然語法簡單,通俗易懂,但是再簡單它也是一門語言,就像一棵大樹,總有一些樹枝是彎彎繞繞的,讓新手看完之後一臉懵逼,今天我們就來說說這幾個點,反正我學的時候是很困惑的!

01.函式裡面的 *args

1).可變引數

這個是什麼鬼,尤其是有其他c,c++語言基礎的人,看到這個點,一定懵逼了,難道是指標,兩個**又是什麼鬼?

其實這個Python裡面的函式入參的幾種形式,假如你來設計一個語言,一個函式fun(),裡面要傳引數進來,要考慮擴充套件性:變數會有很多種形態,有可能是變數,也可能是陣列,也可能是結構體,或者是雜湊陣列。

比如你有一個累加功能的函式:

12684358-94123f276bcd74da

每次呼叫函式都要傳一個列表或者元組進去,非常死板,不靈活,如果我要傳多個列表,多個變數,我又不想改介面,但是改成下面這樣就靈活很多:

12684358-706d1c36ecb196d6

*args:表示可變引數,就是傳入的引數個數是可變的,可以是1個、2個到任意個或者0個,其實就是把一堆引數當作一個陣列(Python列表或者元組傳遞進來)。

02.關鍵字引數 **kwargs

關鍵字引數可以讓你輸入0或者多個含引數名的引數,並且自動組裝為一個字典

12684358-8ae6e540d5841065

你函式的介面設定為**kwargs,這樣的好處,一個是靈活,擴充套件性好,也就是說我預留的了擴充套件的介面,你程式呼叫的時候可以根據自己的需求傳1個,多個或者不傳都可以。

另外:不用太糾集args和kwargs這些英語單詞,只是大家約定這麼叫而已

03.臉萌的@property

有其他經驗的程式設計師,看到這個奇奇怪怪的@加一個關鍵字,一定是一臉懵逼,這其實是Python類裡面的一些封裝。這些都是類的內建裝飾器,有一些特殊的用途!

1).裝飾器@property

我們大部分人都比較熟悉比如Java的get/set方法,比如:

12684358-0d71d9b12ac5e668

2).但是這樣寫比較麻煩,需要通過函式get/set 來訪問屬性

有木有直接對屬性進行操作的同時就可以對屬性進行處理,比如我們呼叫student.score=88,這一個時候會自動呼叫set_score函式,這樣就非常靈活和簡便!

Python裡面為了簡潔和優雅,設計了@property

12684358-1a0c7db69f9e29b8

對於外邊訪問的屬性score,我們通過Python類中的property裝飾器對它進行升級,改造,讓它能變的更加靈活和強大!

其實它就是繫結了一些方法(fget,fset和fdel).尤其是你對屬性進行升級功能而不改變外邊程式碼的時候,這一招就非常有用!

04.傻傻分不清@classmethod和@staticmethod

看完了上面的property,剛剛回過神,現在又來了兩個更大的傢伙是啥,其實這個兩個類裝飾器都是類裡面的概念!

只要是寫程式碼最後一定會走到類而類的封裝和擴充套件是必須要掌握的,如何能有更好的封裝性呢,classmethod和staticmethod就派上用場了!

1).假如有一個場景,計算日期的類

12684358-38553a4f2ba4479c

2).更改需求,如果我們傳入的類初始化是字串型日期

我們目前的類的init函式是一個三個引數的,如果我們希望我們傳入一個字串性的日期"2018-10-8",然後返回像上面的日期2018/10/8,怎麼辦呢?

傳統的做法:

12684358-f51f2d35ec547180

這樣的做法會導致每次初始化的時候,都要先分割成3個引數再匯入類,非常麻煩!

@staticmethod(類的靜態方法就派上場)

12684358-56dd7907b2d976ca

通過靜態函式,直接內建了分割的功能,會簡潔很多,而且封裝性也好很多!

3).但是靜態方法也有弊端

因為靜態方法是硬編碼,如果我們修改了Date這個類的名字,比如叫MyDate這樣的話,會導致我們寫的format_date裡面的程式碼也要改,因為我們直接是return Date()... ,好這個時候類方法classmethod上場了

12684358-abce1121cbff9f94

我們申明瞭一個類方法format_date2,裡面有一個非常關鍵的變數cls,其實它就是類本身,這樣無論我們把類的名字改成什麼,都沒有關係,因為我們返回的就是cls(...),這樣程式碼的柔性就強了很多!

有同學看到這裡會問,那靜態函式還有什麼用處,類方法都能代替了!在做一些類的預處理,或者條件判斷的時候,靜態函式還是很有用的!

05.super是啥

都說Python語言跟英語很類似,語法簡單,通俗易懂,但是看到super這樣關鍵字的時候,會有點懵懂!

其實只要是物件導向的語言,都有類的繼承啊,組合等等。Python當然也有這樣的設計,其實如果學過Java會非常好理解!比如子類要呼叫父類的方法,或者覆蓋父類的方法都會用到super().

1).呼叫父類的方法

12684358-2b5becb085bddf23

有的同學說我是不是可以直接呼叫A.say_hello(self),最好不要,涉及多重繼承的時候就會有問題

2).初始化父類的__init__方法

12684358-722e4632b651133b

06.ABC模組

新手有的時候看到下面的程式碼會很懵,有點丈二和尚摸不著頭腦的趕腳:

12684358-510912a5735c6dda

C++裡面有抽象基類的概念,Python裡面的類在設計的時候,也考慮到了這一點,但是由於Python本身的特性是一切皆物件,大部分的時候都依賴鴨子型別。

為了完成抽象基類的功能,藉助了第三方模組abc(abc是抽象類的縮寫,不是英語abc的意思)

b=Bird()

TypeError: Can't instantiate abstract class Bird with abstract methods fly

Bird繼承ABC,也就是說Bird是一個抽象類,不能被初始化,比如你初始化一下,會報錯的。

這個類的目的就是讓繼承它的子類一定要例項化fly函式,否則子類也永遠無法例項化

12684358-fba2d32a1891185b

其實當你完全熟悉這些用法之後,你要開始思考Python為啥要這麼設計,慢慢的你就會領悟Python這門語言的設計思想,而不是隻是看它的招式,當你明白裡招式背後的含義,恭喜你,你的功力又大漲了!

相關文章