學一門語言貴在堅持用它,不用就淡忘了,而記錄下一篇文章也有助於日後快速回憶。全文分為兩大部分,分別是Python基礎語法和面向對象。
2019年最新Python教程
最近幾年Python程式語言在國內引起不小的轟動,有超越Java之勢,本來在美國這個程式語言就是最火的,應用的非常非常的廣泛,而Python的整體語言難度來講又比Java簡單的很多。尤其是在運維的應用中非常的廣泛,所以之前出了一句話,在如今的時代,運維不學Python,遲早會被淘汰!
由北京尚學堂高淇老師親自錄製,400集python全棧入門到精通的python全套+前端+4個實戰項目,第二季已經新鮮出爐了!小夥伴們快快領取學習吧!
Python作為一種程式語言,被稱為「膠水語言」,更被擁躉們譽為「最美麗」的程式語言,從雲端到客戶端,再到物聯網終端,無所不在,同時還是人工智慧優選的程式語言。
獲取方式:轉發此文+關注 並 私信小編 「 學習」,即可免費獲取!
獲取方式:轉發此文+關注 並 私信小編 「學習」,即可免費獲取
第一部分 Python基礎語法
第一部分 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.6。
提示:如果開發時,無法立即使用 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.3. PyCharm 的設置
PyCharm 的 配置信息 是保存在 用戶家目錄下 的 .PyCharmxxxx.x 目錄下的,xxxx.x 表示當前使用的 PyCharm 的版本號
1.3.1 恢復 PyCharm 的初始設置:
- 關閉正在運行的 PyCharm
- 在終端中執行以下終端命令,刪除 PyCharm 的配置信息目錄:
$ rm -r ~/.PyCharm2016.3
- 重新啟動 PyCharm
1.3.2 PyCharm 安裝和啟動步驟:
- 執行以下終端命令,解壓縮下載後的安裝包
$ tar -zxvf pycharm-professional-2017.1.3.tar.gz
- 將解壓縮後的目錄移動到 /opt 目錄下,可以方便其他用戶使用
/opt 目錄用戶存放給主機額外安裝的軟體
$ sudo mv pycharm-2017.1.3/ /opt/
- 切換工作目錄
$ cd /opt/pycharm-2017.1.3/bin
- 啟動 PyCharm
$ ./pycharm.sh
1.3.3 設置啟動圖標
- 在專業版中,選擇菜單 Tools / Create Desktop Entry... 可以設置任務欄啟動圖標
- 注意:設置圖標時,需要勾選 Create the entry for all users
- 快捷方式文件
- /usr/share/applications/jetbrains-pycharm.desktop
在 ubuntu 中,應用程式啟動的快捷方式通常都保存在 /usr/share/applications 目錄下
1.3.4 卸載之前版本的 PyCharm
要卸載 PyCharm 只需要做以下兩步工作:
- 刪除解壓縮目錄
$ sudo rm -r /opt/pycharm-2016.3.1/
- 刪除家目錄下用於保存配置信息的隱藏目錄
$ rm -r ~/.PyCharm2016.3/
如果不再使用 PyCharm 還需要將 /usr/share/applications/ 下的 jetbrains-pycharm.desktop 刪掉
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 運算符優先級
- 以下表格的算數優先級由高到最低順序排列:
運算符 描述 ** 冪 (最高優先級) * / % // 乘、除、取餘數、取整除 + - 加法、減法 <= < > >= 比較運算符 == != 等於運算符 = %= /= //= -= += *= **= 賦值運算符 is is not 身份運算符 in not in 成員運算符 not or and 邏輯運算符
<補>程序執行原理
Python程序執行示意圖
- 作業系統會首先讓 CPU 把 Python 解釋器 的程序複製到 內存 中
- Python 解釋器 根據語法規則,從上向下 讓 CPU 翻譯 Python 程序中的代碼
- CPU 負責執行翻譯完成的代碼
Python 的解釋器有多大?
- 執行以下終端命令可以查看 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 提供的 內置方法 / 屬性。
序號 方法名 類型 作用 01 __new__ 方法 創建對象時,會被 自動 調用 02 __init__ 方法 對象被初始化時,會被 自動 調用 03 __del__ 方法 對象被從內存中銷毀前,會被 自動 調用 04 __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 中,要 給對象設置屬性,非常的容易,只需要在 類的外部的代碼 中直接通過 對象.設置一個屬性即可,但是不推薦使用:
看完這篇文章,你的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 __init__(self, name):
print("初始化方法 %s" % name)
self.name = name
...
tom = Cat("Tom")
...
lazy_cat = Cat("大懶貓")
...
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 類屬性和實例屬性
類屬性 就是 類對象中定義的屬性通常用來記錄與這個類相關的特徵