前言
學一門語言貴在堅持用它,不用就淡忘了,而記錄下一篇文章也有助于日后快速回憶,全文分為兩大部分,分別是Python基礎語法和面向物件,
入門Python其實很容易,但是我們要去堅持學習,每一天堅持很困難,我相信很多人學了一個星期就放棄了,為什么呢?其實沒有好的學習資料給你去學習,你們是很難堅持的,這是小編收集的Python入門學習資料關注,轉發,私信小編“1”,即可免費領取!希望對你們有幫助
送書
![]() | 關注「web前端營」 回復527532下載 ![]() |
第一部分 Python基礎語法
1. 認識Python
1.1 Python 簡介
Python 的創始人為吉多·范羅蘇姆(Guido van Rossum),
Python 的設計目標:
一門簡單直觀的語言并與主要競爭者一樣強大開源,以便任何人都可以為它做貢獻 代碼像純英語那樣容易理解適用于短期開發的日常任務
Python 的設計哲學:
優雅、明確、簡單
Python 開發者的哲學是:用一種方法,最好是只有一種方法來做一件事
Python 是完全面向物件的語言,在 Python 中一切皆物件,
可擴展性:如果需要一段關鍵代碼運行得更快或者希望某些演算法不公開,可以把這部分程式用 C 或 C++ 撰寫,然后在 Python 程式中使用它們,
1.2. 第一個Python程式
執行 Python 程式的三種方式:
解釋器、互動式運行、IDE運行
Python 是一個格式非常嚴格的程式設計語言,
python 2.x 默認不支持中文,
ASCII 字符只包含 256 個字符,不支持中文
-
Python 2.x 的解釋器名稱是python
-
Python 3.x 的解釋器名稱是python3
為了照顧現有的程式,官方提供了一個過渡版本 ——Python 2.7,
提示:如果開發時,無法立即使用 Python 3.0(還有極少的第三方庫不支持 3.0 的語法),建議
先使用 Python 3.0 版本進行開發 然后使用 Python 2.6、Python 2.7 來執行,并且做一些兼容性的處理
IPython 是一個 python 的互動式 shell,比默認的 python shell 好用得多,它支持 bash shell 命令,適合于學習/驗證 Python 語法或者區域代碼,
集成開發環境(IDE,Integrated Development Environment)——集成了開發軟體需要的所有工具,一般包括以下工具:
-
圖形用戶界面
-
代碼編輯器(支持代碼補全/自動縮進)
-
編譯器/解釋器
-
除錯器(斷點/單步執行)
-
……

PyCharm 是 Python 的一款非常優秀的集成開發環境

PyCharm運行工具列
1.4. 多檔案專案的演練
-
開發專案就是開發一個專門解決一個復雜業務功能的軟體
-
通常每一個專案就具有一個獨立專屬的目錄,用于保存所有和專案相關的檔案
-
在 PyCharm 中,要想讓哪一個 Python 程式能夠執行,必須首先通過滑鼠右鍵的方式執行一下
-
對于初學者而言,在一個專案中設定多個程式可以執行,是非常方便的,可以方便對不同知識點的練習和測驗
-
對于商業專案而言,通常在一個專案中,只有一個可以直接執行的 Python 源程式

讓選中的程式可以執行
2. 注釋
-
注釋的作用
使用用自己熟悉的語言,在程式中對某些代碼進行標注說明,增強程式的可讀性
2.1 單行注釋(行注釋)
-
以 # 開頭,# 右邊的所有東西都被當做說明文字,而不是真正要執行的程式,只起到輔助說明作用
print("hello python")
# 輸出 hello python
`
為了保證代碼的可讀性,# 后面建議先添加一個空格,然后再撰寫相應的說明文字;為了保證代碼的可讀性,注釋和代碼之間 至少要有 兩個空格,
2.2 多行注釋(塊注釋)
-
要在 Python 程式中使用多行注釋,可以用 一對 連續的 三個 引號(單引號和雙引號都可以)
"""
這是一個多行注釋
在多行注釋之間,可以寫很多很多的內容……
"""
print("hello python")
提示:
-
注釋不是越多越好,對于一目了然的代碼,不需要添加注釋
-
對于復雜的操作,應該在操作開始前寫上若干行注釋
-
對于不是一目了然的代碼,應在其行尾添加注釋(為了提高可讀性,注釋應該至少離開代碼 2 個空格)
-
絕不要描述代碼,假設閱讀代碼的人比你更懂 Python,他只是不知道你的代碼要做什么
2.3 代碼規范:
-
Python 官方提供有一系列 PEP(Python Enhancement Proposals) 檔案,其中第 8 篇檔案專門針對Python 的代碼格式給出了建議,也就是俗稱的PEP 8:
檔案地址:https://www.python.org/dev/peps/pep-0008/
谷歌有對應的中文檔案:http://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules/
3. 運算子
3.1 算數運算子
是完成基本的算術運算使用的符號,用來處理四則運算,而“+”和“*”還可以用來處理字串,
運算子 描述 實體 + 加
10 + 20 = 30
- 減
10 - 20 = -10
* 乘
10 * 20 = 200
/ 除
10 / 20 = 0.5
// 取整除 回傳除法的整數部分(商)
9 // 2 輸出結果
4
% 取余數 回傳除法的余數
9 % 2 = 1
** 冪 又稱次方、乘方,
2 ** 3 = 8
3.2 比較(關系)運算子
運算子 描述 == 檢查兩個運算元的值是否相等,如果是,則條件成立,回傳 True != 檢查兩個運算元的值是否不相等,如果是,則條件成立,回傳 True > 檢查左運算元的值是否大于右運算元的值,如果是,則條件成立,回傳 True < 檢查左運算元的值是否小于右運算元的值,如果是,則條件成立,回傳 True >= 檢查左運算元的值是否大于或等于右運算元的值,如果是,則條件成立,回傳 True <= 檢查左運算元的值是否小于或等于右運算元的值,如果是,則條件成立,回傳 True
Python 2.x 中判斷不等于還可以使用 <> 運算子 != 在 Python 2.x 中同樣可以用來判斷不等于
3.3 賦值運算子
-
在 Python 中,使用 = 可以給變數賦值,在算術運算時,為了簡化代碼的撰寫,Python 還提供了一系列的 與算術運算子對應的賦值運算子,注意:賦值運算子中間不能使用空格,
運算子 描述 實體 = 簡單的賦值運算子
c = a + b
# 將 a + b 的運算結果賦值為 c
+= 加法賦值運算子
c += a
# 等效于 c = c + a
-= 減法賦值運算子
c -= a
# 等效于 c = c - a
*= 乘法賦值運算子
c *= a
# 等效于 c = c * a
/= 除法賦值運算子
c /= a
# 等效于 c = c / a
//= 取整除賦值運算子
c //= a
# 等效于 c = c // a
%=取模(余數)賦值運算子
c %= a
# 等效于 c = c % a
**= 冪賦值運算子
c **= a
# 等效于 c = c ** a
3.4 身份運算子
身份運算子比較兩個物件的記憶體位置,常用的有兩個身份運算子,如下所述:
運算子 描述 示例 is 判斷兩個識別符號是不是參考同一個物件 x is y,類似 id(x) == id(y) is not 判斷兩個識別符號是不是參考不同物件 x is not y,類似 id(a) != id(b)
辨析
-
is 用于判斷 兩個變數參考的物件是否為同一個
-
== 用于判斷 參考變數的值是否相等
3.5 成員運算子
Python成員運算子測驗給定值是否為序列中的成員, 有兩個成員運算子,如下所述:
運算子 描述
in 如果在指定的序列中找到一個變數的值,則回傳true,否則回傳false,
not in 如果在指定序列中找不到變數的值,則回傳true,否則回傳false,
3.6 邏輯運算子
運算子 邏輯運算式 描述 and x and y 只有 x 和 y 的值都為 True,才會回傳 True<br />否則只要 x 或者 y 有一個值為 False,就回傳 False or x or y 只要 x 或者 y 有一個值為 True,就回傳 True<br />只有 x 和 y 的值都為 False,才會回傳 False not not x 如果 x 為 True,回傳 False<br />如果 x 為 False,回傳 True
3.7 運算子優先級
-
以下表格的算數優先級由高到最低順序排列:
運算子 描述
** 冪 (最高優先級)
* / % // 乘、除、取余數、取整除 + - 加法、減法
<= < > >= 比較運算子
== != 等于運算子
= %= /= //= -= += *= **= 賦值運算子
s is not 身份運算子
in not in 成員運算子
not or and 邏輯運算子
<補>程式執行原理

Python程式執行示意圖
-
作業系統會首先讓CPU把Python 解釋器的程式復制到記憶體中
-
Python 解釋器根據語法規則,從上向下讓CPU翻譯Python 程式中的代碼
-
CPU負責執行翻譯完成的代碼
Python 的解釋器有多大?
-
執行以下終端命令可以查看 Python 解釋器的大小
# 1. 確認解釋器所在位置$ which python# 2. 查看 python 檔案大小(只是一個軟鏈接)$ ls -lh /usr/bin/python# 3. 查看具體檔案大小$ ls -lh /usr/bin/python2.7
4. 變數
4.1 變數定義
-
在 Python 中,每個變數在使用前都必須賦值,變數賦值以后該變數才會被創建
-
可以用其他變數的計算結果來定義變數
-
變數名 只有在第一次出現才是定義變數
變數名 = 值
使用互動式方式,如果要查看變數內容,直接輸入變數名即可,不需要使用 print 函式
使用解釋器執行,如果要輸出變數的內容,必須要要使用 print 函式
4.2 變數的型別
-
在 Python 中定義變數是不需要指定型別(在其他很多高級語言中都需要),Python 可以根據 = 等號右側的值,自動推匯出變數中存盤資料的型別
-
資料型別可以分為數字型和非數字型數字型 整型 (int):Python3中的所有整數都表示為長整數, 因此,長整數沒有單獨的數字型別, 浮點型(float)
布爾型(bool) :真 True 非 0 數 —— 非零即真,假 False 0, 復數型 (complex):復數是由x + yj表示的有序對的實數浮點陣列成,其中x和y是實數,j是虛數單位,
非數字型:有些運算子還支持這些資料型別,詳見4.4.5.3 運算子, -
字串(str):加號(+)是字串連接運算子,星號(*)是重復運算子,
-
串列(list) 元組(tuple) 字典(dict)
提示:在 Python 2.x 中,整數根據保存數值的長度還分為:
int(整數) long(長整數)
-
使用 type 函式可以查看一個變數的型別
In [1]: type(name)
<補>不同型別變數之間的計算
-
數字型變數之間可以直接計算
-
在 Python 中,兩個數字型變數是可以直接進行 算數運算的
-
如果變數是 bool 型,在計算時 True 對應的數字是 1 False 對應的數字是 0
-
字串變數之間使用 + 拼接字串
-
字串變數可以和整數使用 * 重復拼接相同的字串
-
數字型變數和字串之間不能進行其他計算
<補>從鍵盤獲取輸入資訊:input
-
在 Python 中可以使用 input 函式從鍵盤等待用戶的輸入
-
用戶輸入的任何內容Python 都認為是一個字串
字串變數 = input("提示資訊:")
<補>型別轉換函式
函式 說明 int(x) 將 x 轉換為一個整數 float(x) 將 x 轉換到一個浮點數 str(x) 將物件x轉換為字串表示形式 tuple(s) 將s轉換為元組 list(s) 將s轉換為串列
price = float(input("請輸入價格:"))
<補>格式化輸出:print
-
如果希望輸出文字資訊的同時,一起輸出資料,就需要使用到格式化運算子
-
% 被稱為格式化運算子,專門用于處理字串中的格式 包含 % 的字串,被稱為格式化字串% 和不同的字符連用,不同型別的資料需要使用不同的格式化字符
格式化字符 含義 %s 字串 %d 有符號十進制整數,%06d 表示輸出的整數顯示位數,不足的地方使用 0 補全 %f 浮點數,%.2f 表示小數點后只顯示兩位 %% 輸出 %
-
語法格式如下:
print("格式化字串" % 變數1)print("格式化字串" % (變數1, 變數2...))
4.4.5 公共方法和變數的高級應用
4.4.5.1 內置函式
Python 包含了以下內置函式:
函式 描述 備注 len(item) 計算容器中元素個數 del(item) 洗掉變數 del 有兩種方式 max(item) 回傳容器中元素最大值 如果是字典,只針對 key 比較 min(item) 回傳容器中元素最小值 如果是字典,只針對 key 比較 cmp(item1, item2) 比較兩個值,-1 小于 / 0 相等 / 1 大于Python 3.x 取消了 cmp 函式
注意:字串比較符合以下規則: "0" < "A" < "a",
4.4.5.2 切片
描述 Python 運算式 結果 支持的資料型別 切片 "0123456789"[::-2] "97531" 字串、串列、元組
-
切片使用索引值來限定范圍,從一個大的字串中切出小的字串
-
串列和元組都是有序的集合,都能夠通過索引值獲取到對應的資料
-
字典是一個無序的集合,是使用鍵值對保存資料
面向物件編程 —— Object Oriented Programming 簡寫 OOP
-
面向程序 —— 怎么做?
把完成某一個需求的 所有步驟 從頭到尾 逐步實作根據開發需求,將某些 功能獨立 的代碼 封裝 成一個又一個 函式最后完成的代碼,就是順序地呼叫 不同的函式特點:
注重 步驟與程序,不注重職責分工如果需求復雜,代碼會變得很復雜開發復雜專案,沒有固定的套路,開發難度很大! -
面向物件 —— 誰來做? 相比較函式,面向物件 是更大的封裝,根據職責在 一個物件中封裝多個方法 在完成某一個需求前,首先確定 職責 —— 要做的事情(方法)
根據 職責 確定不同的 物件,在 物件 內部封裝不同的 方法(多個)最后完成的代碼,就是順序地讓 不同的物件 呼叫 不同的方法特點:
注重 物件和職責,不同的物件承擔不同的職責更加適合應對復雜的需求變化,是專門應對復雜專案開發,提供的固定套路需要在面向程序基礎上,再學習一些面向物件的語法 -
類和物件
類是對一群具有相同特征 或者 行為 的事物的一個統稱,是抽象的,特征 被稱為屬性,行為 被稱為方法,
物件是 由類創建出來的一個具體存在,是類的實體化,
在程式開發中,要設計一個類,通常需要滿足一下三個要素:類名這類事物的名字,滿足大駝峰命名法屬性這類事物具有什么樣的特征方法這類事物具有什么樣的行為
2. 面向物件基礎語法
2.1 dir 內置函式和內置方法
在 Python 中物件幾乎是無所不在的,我們之前學習的變數、資料、函式都是物件,
在 Python 中可以使用以下兩個方法驗證:
-
在 識別符號 / 資料 后輸入一個點 .,然后按下 TAB 鍵,iPython 會提示該物件能夠呼叫的方法串列,
-
使用內置函式 dir 傳入 識別符號 / 資料,可以查看物件內的所有屬性及方法,
提示__方法名__格式的方法是 Python 提供的 內置方法 / 屬性,
方法名 型別 作用
__new__ 方法創建物件時,會被 自動 呼叫
__init__ 方法物件被初始化時,會被 自動 呼叫
__del__ 方法物件被從記憶體中銷毀前,會被 自動 呼叫
__str__ 方法回傳物件的描述資訊,print 函式輸出使用
提示利用好 dir() 函式,在學習時很多內容就不需要死記硬背了,
2.2 定義簡單的類(只包含方法)
面向物件是更大的封裝,在 一個類中封裝多個方法,這樣通過這個類創建出來的物件,就可以直接呼叫這些方法了!
定義一個只包含方法的類:
class 類名:
def 方法1(self, 引數串列):
pass
def 方法2(self, 引數串列):
pass
方法的定義格式和之前學習過的函式幾乎一樣,區別在于第一個引數必須是 self,
注意:類名的 命名規則 要符合大駝峰命名法,
當一個類定義完成之后,要使用這個類來創建物件,語法格式如下:
物件變數 = 類名()
在面向物件開發中,參考的概念是同樣適用的!
使用 print輸出 物件變數,默認情況下,是能夠輸出這個變數 參考的物件 是 由哪一個類創建的物件,以及 在記憶體中的地址(十六進制表示),
提示:在計算機中,通常使用 十六進制 表示 記憶體地址,
如果在開發中,希望使用 print輸出 物件變數 時,能夠列印自定義的內容,就可以利用 __str__這個內置方法了:
class Cat:
def __init__(self, new_name):
self.name = new_name
print("%s 來了" % self.name)
def __del__(self):
print("%s 去了" % self.name)
def __str__(self):
return "我是小貓:%s" % self.name
tom = Cat("Tom")
print(tom)
注意:__str__方法必須回傳一個字串,
2.3 方法中的 self 引數
在 Python 中,要 給物件設定屬性,非常的容易,只需要在類的外部的代碼中直接通過 物件.設定一個屬性即可,但是不推薦使用:
class Cat:
"""這是一個貓類"""
def eat(self):
print("小貓愛吃魚") def drink(self):
print("小貓在喝水")
tom = Cat()
# 給物件設定屬性tom.name = "Tom"
因為:物件屬性的封裝應該封裝在類的內部
由哪一個物件呼叫的方法,方法內的 self就是哪一個物件的參考
-
在類封裝的方法內部,self 就表示當前呼叫方法的物件自己,在方法內部:
可以通過 self.訪問物件的屬性,也可以通過 self.呼叫物件的其他方法, -
呼叫方法時,程式員不需要傳遞 self 引數,
-
在 類的外部,通過變數名.訪問物件的 屬性和方法
在 類封裝的方法中,通過 self.訪問物件的 屬性和方法
2.4 初始化方法:__init__
-
當使用 類名() 創建物件時,會 自動 執行以下操作:
為物件在記憶體中分配空間—— 創建物件
為物件的屬性設定初始值—— 初始化方法(__init__)
__init__ 方法是專門用來定義一個類具有哪些屬性的方法!
-
在 __init__ 方法內部使用 self.屬性名 = 屬性的初始值 就可以定義屬性,定義屬性之后,再使用 類創建的物件,都會擁有該屬性,
-
在開發中,如果希望在 創建物件的同時,就設定物件的屬性,可以對 __init__ 方法進行改造: 把希望設定的屬性值,定義成 __init__方法的引數 在方法內部使用 self.屬性 = 形參 接收外部傳遞的引數 在創建物件時,使用 類名(屬性1, 屬性2...) 呼叫
class Cat:
"""這是一個貓類"""
def eat(self):
print("小貓愛吃魚") def drink(self):
print("小貓在喝水")
tom = Cat()
# 給物件設定屬性
tom.name = "Tom"
2.5 私有屬性和私有方法
應用場景
-
在實際開發中,物件的某些屬性或方法可能只希望在物件的內部被使用,而不希望在外部被訪問到
-
私有屬性就是物件不希望公開的屬性
-
私有方法就是物件不希望公開的方法
定義方式
-
在定義屬性或方法時,在屬性名或者方法名前增加兩個下劃線,定義的就是私有屬性或方法:

私有屬性和私有方法
偽私有屬性和私有方法
Python 中,并沒有 真正意義 的 私有
在給 屬性、方法 命名時,實際是對名稱做了一些特殊處理,使得外界無法訪問到
處理方式:在 名稱 前面加上_類名 => _類名__名稱
# 私有屬性,外部不能直接訪問到
print(xiaofang._Women__age)
# 私有方法,外部不能直接呼叫
xiaofang._Women__secret()
提示:在日常開發中,不要使用這種方式,訪問物件的 私有屬性 或 私有方法,
3. 封裝、繼承和多型
面向物件三大特性:
-
封裝根據 職責 將 屬性 和 方法 封裝 到一個抽象的 類 中
-
繼承實作代碼的重用,相同的代碼不需要重復的撰寫
-
多型不同的物件呼叫相同的方法,產生不同的執行結果,增加代碼的靈活度
3.1 繼承
3.1.1 單繼承
繼承的概念:子類 擁有 父類 以及 父類的父類 中封裝的所有 屬性 和 方法,
class 類名(父類名):
pass
當 父類 的方法實作不能滿足子類需求時,可以對方法進行重寫(override)
重寫 父類方法有兩種情況:
-
覆寫父類的方法:父類的方法實作 和 子類的方法實作完全不同
具體的實作方式,就相當于在 子類中 定義了一個 和父類同名的方法并且實作, -
對父類方法進行擴展:子類的方法實作 中 包含 父類的方法實作
在子類中 重寫 父類的方法;在需要的位置使用 super().父類方法 來呼叫父類方法的執行代碼;其他的位置針對子類的需求,撰寫 子類特有的代碼實作,
關于 super
-
在 Python 中 super 是一個 特殊的類
-
super()就是使用 super 類創建出來的物件
-
最常 使用的場景就是在 重寫父類方法時,呼叫 在父類中封裝的方法實作
呼叫父類方法的另外一種方式:在 Python 2.x 時,如果需要呼叫父類的方法,還可以使用以下方式:父類名.方法(self),目前在 Python 3.x 還支持這種方式,但不推薦使用,因為一旦 父類發生變化,方法呼叫位置的 類名 同樣需要修改,
父類的 私有屬性 和 私有方法
子類物件不能在自己的方法內部,直接訪問 父類的 私有屬性 或 私有方法
子類物件 可以通過 父類 的公有方法間接訪問到 私有屬性 或 私有方法
私有屬性、方法 是物件的隱私,不對外公開,外界 以及 子類 都不能直接訪問 私有屬性、方法 通常用于做一些內部的事情
3.1.2 多繼承
子類 可以擁有多個父類,并且具有 所有父類 的 屬性 和 方法,例如:孩子 會繼承自己 父親 和 母親 的 特性,
class 子類名(父類名1, 父類名2...):
pass
Python 中的 MRO演算法(Method Resolution Order)
-
如果 不同的父類 中存在 同名的方法,子類物件 在呼叫方法時,會呼叫 哪一個父類中的方法呢?
提示:開發時,應該盡量避免這種容易產生混淆的情況! —— 如果 父類之間 存在 同名的屬性或者方法,應該盡量避免使用多繼承, -
Python 中針對 類 提供了一個 內置屬性__mro__ 可以查看 方法 搜索順序 在搜索方法時,是按照mro的輸出結果 從左至右 的順序查找的 如果在當前類中 找到方法,就直接執行,不再搜索 如果 沒有找到,就查找下一個類 中是否有對應的方法,如果找到,就直接執行,不再搜索 如果找到最后一個類,還沒有找到方法,程式報錯
MRO 是 method resolution order —— 方法搜索順序,主要用于 在多繼承時判斷 方法、屬性 的呼叫 路徑
新式類與舊式(經典)類
-
新式類:以 object 為基類的類,推薦使用
-
經典類:不以 object為基類的類,不推薦使用
在 Python 3.x 中定義類時,如果沒有指定父類,會默認使用 object作為該類的 基類 —— Python 3.x 中定義的類都是新式類,在 Python 2.x 中定義類時,如果沒有指定父類,則不會以 object 作為 基類,
-
為了保證撰寫的代碼能夠同時在 Python 2.x 和 Python 3.x 運行!今后在定義類時,如果沒有父類,建議統一繼承自 object:
class 類名(object):
pass
object 是 Python 為所有物件提供的 基類,提供有一些內置的屬性和方法,可以使用 dir(object) 函式查看,
3.2 多型
面向物件三大特性:
-
封裝 根據 職責 將 屬性 和 方法 封裝 到一個抽象的 類 中 定義類的準則
-
繼承 實作代碼的重用,相同的代碼不需要重復的撰寫 設計類的技巧 子類針對自己特有的需求,撰寫特定的代碼
-
多型 不同的 子類物件 呼叫相同的 父類方法,產生不同的執行結果 增加代碼的靈活度 以 繼承 和 重寫父類方法 為前提 呼叫方法的技巧,不會影響到類的內部設計
多型 更容易撰寫出出通用的代碼,做出通用的編程,以適應需求的不斷變化!
案例:
在 Dog 類中封裝方法 game:普通狗只是簡單的玩耍
定義 XiaoTianDog 繼承自 Dog,并且重寫 game 方法:哮天犬需要在天上玩耍
定義 Person 類,并且封裝一個 和狗玩 的方法:在方法內部,直接讓 狗物件 呼叫 game 方法

多型示例
Person 類中只需要讓 狗物件 呼叫 game 方法,而不關心具體是 什么狗,
4. 類屬性和類方法
4.1 類的結構
通常會把:
創建出來的 物件 叫做類的實體
創建物件的 動作 叫做實體化
物件的屬性 叫做實體屬性
物件呼叫的方法 叫做實體方法
每一個物件 都有自己獨立的記憶體空間,保存各自不同的屬性
多個物件的方法,在記憶體中只有一份,在呼叫方法時,需要把物件的參考傳遞到方法內部

各個不同的屬性,獨一份的方法
在 Python 中,類是一個特殊的物件,
Python 中 一切皆物件:
class AAA: 定義的類屬于類物件obj1 = AAA() 屬于實體物件
在程式運行時,類同樣會被加載到記憶體
在程式運行時,類物件在記憶體中只有一份,使用 一個類可以創建出很多個物件實體
除了封裝實體的屬性和方法外,類物件還可以擁有自己的屬性和方法——類屬性、類方法,通過 類名. 的方式可以 訪問類的屬性 或者 呼叫類的方法

類的結構
4.2 類屬性和實體屬性
類屬性 就是類物件中定義的屬性
通常用來記錄與這個類相關的特征
類屬性不會用于記錄具體物件的特征
示例:
定義一個 工具類,每件工具都有自己的 name:
需求—— 知道使用這個類,創建了多少個工具物件?

屬性的獲取機制
在 Python 中 屬性的獲取 存在一個向上查找機制

因此,要訪問類屬性有兩種方式:
-
類名.類屬性
-
物件.類屬性 (不推薦,因為如果使用 物件.類屬性 = 值 賦值陳述句,只會給物件添加一個屬性,而不會影響到類屬性的值)
4.3 類方法和靜態方法
4.3.1 類方法
-
類屬性 就是針對類物件定義的屬性 使用 賦值陳述句 在 class 關鍵字下方可以定義 類屬性 類屬性 用于記錄與這個類相關的特征
-
類方法就是針對類物件定義的方法 在類方法內部可以直接訪問類屬性或者呼叫其他的類方法
語法如下
@classmethoddef 類方法名(cls):
pass
-
類方法需要用修飾器@classmethod 來標識,告訴解釋器這是一個類方法
-
類方法的第一個引數應該是 cls 由哪一個類呼叫的方法,方法內的 cls 就是哪一個類的參考這個引數和實體方法的第一個引數是 self 類似提示使用其他名稱也可以,不過習慣使用 cls
-
通過類名.呼叫類方法,呼叫方法時,不需要傳遞 cls 引數
-
在方法內部可以通過 cls.訪問類的屬性也可以通過 cls.呼叫其他的類方法
示例
-
定義一個工具類,每件工具都有自己的 name
-
需求—— 在類封裝一個 show_tool_count 的類方法,輸出使用當前這個類,創建的物件個數
@classmethoddef show_tool_count(cls):
"""顯示工具物件的總數"""
print("工具物件的總數 %d" % cls.count)
4.3.2 靜態方法
-
在開發時,如果需要在類中封裝一個方法,這個方法: 既不需要訪問實體屬性或者呼叫實體方法也不需要訪問類屬性或者呼叫類方法
-
這個時候,可以把這個方法封裝成一個靜態方法
語法如下
@staticmethoddef 靜態方法名():
pass
-
靜態方法需要用修飾器@staticmethod 來標識,告訴解釋器這是一個靜態方法
-
通過類名.呼叫靜態方法
示例:
-
靜態方法 show_help 顯示游戲幫助資訊
-
類方法 show_top_score 顯示歷史最高分
-
實體方法 start_game 開始當前玩家的游戲

探索:
-
實體方法 —— 方法內部需要訪問 實體屬性實體方法 內部可以使用 類名. 訪問類屬性
-
類方法 —— 方法內部只需要訪問 類屬性
-
靜態方法 —— 方法內部,不需要訪問 實體屬性 和 類屬性
5. 單例
5.1 單例設計模式
-
設計模式設計模式是前人作業的總結和提煉,通常,被人們廣泛流傳的設計模式都是針對某一特定問題的成熟的解決方案 使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性
-
單例設計模式目的—— 讓類創建的物件,在系統中只有唯一的一個實體每一次執行 類名() 回傳的物件,記憶體地址是相同的
-
單例設計模式的應用場景音樂播放物件回收站物件列印機物件 ……
5.2 靜態方法: __new__
-
使用類名()創建物件時,Python 的解釋器首先會 呼叫 __new__ 方法為物件分配空間
-
__new__ 是一個 由 object 基類提供的內置的靜態方法,主要作用有兩個: 在記憶體中為物件分配空間回傳物件的參考
-
Python 的解釋器獲得物件的參考后,將參考作為第一個引數,傳遞給 __init__ 方法
重寫 __new__ 方法 的代碼非常固定!
-
重寫 __new__ 方法一定要return super().__new__(cls),否則 Python 的解釋器得不到分配了空間的物件參考,就不會呼叫物件的初始化方法
-
注意:__new__ 是一個靜態方法,在呼叫時需要主動傳遞cls 引數


5.3 Python 中的單例
-
單例—— 讓類創建的物件,在系統中只有唯一的一個實體定義一個類屬性,初始值是 None,用于記錄單例物件的參考重寫 __new__ 方法 如果類屬性is None,呼叫父類方法分配空間,并在類屬性中記錄結果 回傳類屬性中記錄的物件參考


只執行一次初始化作業
-
在每次使用 類名() 創建物件時,Python 的解釋器都會自動呼叫兩個方法: __new__ 分配空間 __init__ 物件初始化
-
在對 __new__ 方法改造之后,每次都會得到第一次被創建物件的參考
-
但是:初始化方法還會被再次呼叫
需求
-
讓初始化動作只被執行一次
解決辦法
-
定義一個類屬性 init_flag 標記是否執行過初始化動作,初始值為 False
-
在 __init__ 方法中,判斷 init_flag,如果為 False 就執行初始化動作
-
然后將 init_flag 設定為 True
-
這樣,再次自動呼叫 __init__ 方法時,初始化動作就不會被再次執行了

Tips
1、Python 能夠自動的將一對括號內部的代碼連接在一起:
'''
**需求**
* 定義 `input_password` 函式,提示用戶輸入密碼
* 如果用戶輸入長度 < 8,拋出例外
* 如果用戶輸入長度 >=8,回傳輸入的密碼
'''def input_password():
# 1\. 提示用戶輸入密碼
pwd = input("請輸入密碼:") # 2\. 判斷密碼長度,如果長度 >= 8,回傳用戶輸入的密碼
if len(pwd) >= 8: return pwd # 3\. 密碼長度不夠,需要拋出例外
# 1> 創建例外物件 - 使用例外的錯誤資訊字串作為引數
ex = Exception("密碼長度不夠") # 2> 拋出例外物件
raise extry:
user_pwd = input_password()
print(user_pwd)except Exception as result:
print("發現錯誤:%s" % result)
2、一個物件的 屬性 可以是 另外一個類創建的物件,
3、在__init__方法中定義類的屬性時,如果 不知道設定什么初始值,可以設定為 None):None 關鍵字 表示 什么都沒有,表示一個空物件,沒有方法和屬性,是一個特殊的常量,可以將 None 賦值給任何一個變數,
在 Python 中針對 None 比較時,建議使用is 判斷
4、eval() 函式十分強大 —— 將字串 當成 有效的運算式 來求值 并 回傳計算結果

-
在開發時千萬不要使用 eval 直接轉換 input 的結果,舉個例子:
-
__import__('os').system('ls')
# 等價代碼import osos.system("終端命令")
?END
送書
![]() | 關注「web前端營」 回復527522下載 ![]() |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/271359.html
標籤:python



