1. 程式人生 > >Python常忘的進階知識(上)

Python常忘的進階知識(上)

0.目錄

1.面向物件

函式與方法的區別:

  • C、C++ 一般稱函式
  • Java、C# 一般稱方法
  • 方法:設計層面
  • 函式:程式執行、過程式的一種稱謂

建構函式的定義:

可以顯式地呼叫建構函式:

顯式地呼叫建構函式返回了什麼?

ps:在建構函式中不能指定return的內容,只能返回None

1.2 類變數與例項變數

類變數與例項變數的區別:

類與物件的變數查詢順序:
__dict__ 變數儲存著當前物件所有的相關的變數:

當物件中不存在name的例項變數時,會去尋找類變數,還沒有的話會去父類中繼續尋找:

類的相關變數:

1.3 例項方法、類方法、靜態方法

self與例項方法:

  • self 改成 this 也可以正常使用
  • self 就是當前呼叫方法的物件
  • self 代表著例項而不是類

在例項方法中訪問例項變數與類變數有兩種方法:

  1. 類.變數名
  2. self.__class__.變數名

定義和呼叫類方法的方法:

定義和呼叫靜態方法的方法:

ps:不需要引數self或者cls
pps:能用靜態方法的地方大都能用類方法代替,不建議使用靜態方法

1.4 公開和私有:沒有什麼是不能訪問的

定義私有的方法:
在資料成員名稱或者方法名稱之前加上 __ 即可

__name已經被置為私有了,此時訪問student1.__name由於Pyhton的動態性,實際上是動態建立了student1.__name,與物件的內建成員變數__name是不同的。
直接訪問student2.__name,果然報錯:

實際上__name儲存的是_Student__name:

所以說沒有什麼是不能訪問的:

1.5 繼承

繼承的方法:

子類呼叫父類的建構函式需要傳遞self(不推薦的方法):

子類方法呼叫父類方法:super關鍵字(推薦的方法)

2.正則表示式

2.1 Python內建函式與正則表示式

初識正則表示式:
1.正則表示式是一個特殊的字元序列,用來檢測一個字串是否與我們所設定的這樣的字元序列相匹配
2.快速檢索文字,實現一些替換文字的操作,比如:

  • 檢查一串數字是否是電話號碼
  • 檢測一個字串是否符合email
  • 把一個文本里指定的單詞替換為另外一個單詞

判斷字串是否包含'Python'(使用Python內建函式):

判斷字串是否包含'Python'(使用正則表示式):

正則表示式的靈魂在於規則

2.2 元字元、字符集、概括字符集

元字元:
找出字串中的所有數字:

字符集:
1.找出中間字元是c或f的單詞

2.找出中間字元不是c也不是f的單詞

3.找出中間字元是c或d或e或f的單詞

概括字符集:
數字——\d —— 等價於[0-9]
非數字——\D —— 等價於[^0-9]
字母、數字、下劃線——\w——等價於[A-Za-z0-9_]
非字母、數字、下劃線——\W——等價於[^A-Za-z0-9_]
任何空白字元,包括空格、製表符、換頁符等等——\s——等價於[ \f\n\r\t\v]
任何非空白字元——\S——等價於[^ \f\n\r\t\v]
除換行符(\n、\r)之外的任何單個字元——.

2.3 貪婪與非貪婪

找出3個字母組成的單詞:

找出3至6個字母組成的單詞(預設是貪婪模式):

使用 ? 改為非貪婪模式:

2.4 匹配0次1次或者無限多次

匹配前面的子表示式0次或多次—— *

匹配前面的子表示式1次或多次—— +

匹配前面的子表示式0次或1次—— ?

2.5 邊界匹配符

判斷QQ號是不是4到8位的QQ號:

加入邊界控制符:

^ —— 表示從字串的開始位置匹配
$ —— 表示從字串的結束位置匹配

邊界控制符的作用:

2.6 匹配模式引數

re.I——忽略大小寫匹配:

ps:多個模式之間可以用 | 隔開,表示且關係

re.S——點號. 可以匹配包括換行符(\n、\r)在內的任何單個字元:

2.7 re.sub正則替換

用於查詢成功後替換:

sub第4個引數count預設為0,表示無限匹配。count表示所能替換的最大次數:

Python內建函式實現替換(replace()函式相當於正則表示式的簡化版,也有count):

sub強大之處在於第2個引數可以是函式:
1.可以看到C#消失了:

2.value的值:一個物件

3.用group()函式取出匹配值:

把函式作為引數傳遞:

2.8 search與match函式

match從字串的首字母開始匹配,如果沒有找到相應的匹配結果,將返回None:

search搜尋整個字串,直到找到第一個滿足正則表示式的結果,然後將匹配的結果返回:

search與match都只會匹配一次,找到後立馬停止搜尋
使用group返回值,使用span返回位置:

2.9 group分組

group(0)永遠記錄的是正則表示式完整的匹配結果,如果要訪問完整的匹配結果內部的某個分組的話,必須從1開始訪問:

使用findall()函式簡單得多:

可以有多個分組:


3.JSON

3.1 理解JSON

JSON:JavaScript Object Notation(JavaScript物件標記)
JSON是一種輕量級的資料交換格式JSON是一種資料格式
字串是JSON的表現形式
符合JSON格式的字串叫做JSON字串
JSON優勢:

  • 易於閱讀
  • 易於解析
  • 網路傳輸效率高
  • 跨語言交換資料

    3.2 反序列化

    json中key和value必須用雙引號括起來,數字不需要:

JSON Object → Python dict或JSON array → Python list:

ps:JSON中布林值是小寫的,Python中布林值首字母大寫

反序列化—— 字串 → 某種語言中的某種資料結構

3.3 序列化

序列化—— 某種語言中的某種資料結構 → JSON字串

Python list → JSON字串:

4.列舉

4.1 列舉其實是一個類

定義VIP,輸出黃鑽:

列舉和普通類相比有什麼優勢:
普通類——可變,沒有防止相同標籤的功能
列舉——不能更改,有防止相同標籤的功能

4.2 列舉型別、列舉名稱與列舉值

取值:

取標籤名稱:

VIP.GREEN和VIP.GREEN.name的區別:

通過列舉名稱獲取列舉型別:

遍歷列舉:

4.3 列舉的比較運算

能做的比較:

4.4 列舉的遍歷與轉換

列舉注意事項:
可以有相同值,但是此時GREEN算作YELLOW的別名:

此時遍歷列舉:

如何遍歷包括別名的列舉:

不用items():

列舉轉換:
如何通過列舉值轉化為列舉型別?(並不是真正的型別轉換)

4.5 限制列舉

限制值為整數——IntEnum:

限制相同值——unique:

列舉在Python中實現的是單例模式,即對列舉型別不能例項化。

5.閉包

5.1 一切皆物件

在其他語言中:

  • 函式只是一段可執行的程式碼,常駐於記憶體中,並不是物件
  • 函式不能例項化

Python中一切皆物件:

  • 把函式當作另外一個函式的引數,傳遞到另外的函式裡
  • 把一個函式當作另外一個函式的返回結果
  • 函式是物件

    5.2 什麼是閉包

    不可以直接呼叫curve():

間接呼叫curve():

a*x*x

模組中呼叫curve()時,內部a的值不取模組中的變數a,而仍然是定義時的環境變數:(也就是說return curve時實際上不是返回一個函式,而是返回一個閉包)

閉包 = 函式 + 環境變數(函式定義時)

  • 環境變數在定義函式的外部
  • 環境變數不能是全域性變數

閉包的環境變數實質是儲存在內建變數 __closure__ 中:

取出閉包的環境變數:__closure__[0].cell_contents

5.3 閉包的經典誤區

這不是閉包:

這才是閉包:

環境變數應該被引用,且不能被當成一個變數進行賦值,否則就不是閉包!

5.4 非閉包解決與閉包解決

問題:編寫函式,傳入引數x代表旅行者走了x步,計算旅行者迄今為止已經走過的路程result,初始值result為0。

  • 即傳入x=0得result=0
  • 傳入x=1得result=1
  • 傳入x=2得result=3
  • 傳入x=5得result=8

非閉包解決:global宣告是全域性變數

閉包解決:nonlocal宣告不是區域性變數(origin這個全域性變數並沒有被改變)

通過閉包在模組中呼叫了局部變數(環境變數)
閉包的問題:環境變數常駐於記憶體中,容易造成記憶體洩漏

6.函數語言程式設計

6.1 匿名函式與lambda表示式

匿名函式——定義函式時不需要定義函式名
lambda定義函式:

三元表示式(如果x大於y,返回x,否則返回y):
其他語言中——x > y ? x : y
Python中——x if x > y else y

6.2 map與lambda

map是一個類,不是函式
求列表中每個數的平方(迴圈實現):

求列表中每個數的平方(map實現):

map將傳入序列的每一項都會執行傳入函式的操作。
map相當於數學上的對映。

map與lambda:
1.map的真正開啟方式

2.map可以傳遞多個引數

3.引數不相等時的結果

6.3 reduce

from functools import reduce
reduce是一個函式,不是類
reduce()裡面的第一個函式引數一定要有兩個引數:

reduce做的是連續的計算,每一次lambda表示式的計算結果將作為下一次的lambda表示式的引數進行運算!

reduce的第三個引數將作為初始值進行運算!

6.4 filter

filter(過濾):幫助我們過濾掉一些不需要的元素,或者是一些不符合規定的元素
過濾掉為0的元素:

filter要求lambda表示式必須返回可以代表真假的:

filter根據lambda表示式返回的結果判斷這個元素是否要保留在序列裡,如果返回的是False,那麼filter將過濾這個元素!