摘要:本文收納了Python學習者經常使用的庫和包,並介紹了Python使用中熱門的問題。
01、Python 簡介
什么是 Python
- 一種面向對象的高級動態可解釋型腳本語言。
- Python 解釋器一次讀取一行代碼,將其解釋為低級機器語言 (如字節代碼) 並執行它。
- 因此這種語言經常會引發運行錯誤。
為什么選擇 Python (優勢)
- Python 是當前最流行的語言,因為它更容易編碼且具有很強的可解釋性。
- Python 是一種面向對象的編程語言,也可用於編寫一些功能代碼。
- Python 是能夠很好地彌補業務和開發人員之間差距。
- 與其他語言 (如 C#/Java) 相比,Python 程序被推向市場的時間更短。
- Python 自帶大量的機器學習和分析包。
- 大量社區和書籍可用於支持 Python 開發人員。
- 從預測分析到UI,幾乎所有類型的應用程序都可以用 Python 實現。
- Python 程序無需聲明變量類型。 因此,所構建的應用程序能有更快的運行速度。
為什么不選擇 Python (劣勢)
- 與其他語言 (C++,C#,Java) 相比,Python 程序的運行更慢,這是因為Python 中缺少類似 Just In Time 優化器的支持。
- Python 語法空白約束給新手編碼實現帶來一些困難。
- Python 不像 R 語言那樣提供高級的統計功能。
- Python 不適合進行低級系統和硬件交互。
Python 是如何工作
下圖展示了 Python 在機器上的運行機制。這里的關鍵是解釋器,它是負責將高級的 Python 語言編譯成低級的機器語言,以便理解。
02、變量——目標類型及范圍
- 可在程序中使用的變量存儲信息,如保存用戶輸入,程序的本地狀態等。
- Python 中的變量以名字命名。
Python 中變量類型包括數字,字符串,集合,列表,元組和字典,這些都是標准的數據類型。
聲明並給變量賦值
如下所示:這里首先分別為變量 myFirstVariable 分配整型數值1,字符串“Hello You”。由於 Python 中的數據類型是動態變化的,因此這種重復賦值操作是可以實現的。
Python 中變量賦值操作又稱為綁定 (blinding)。
數值型
如下所示,Python 支持整型,小數,浮點型數據。
此外,也能支持長整型,以 L 為后綴表示,如999999999999L。
字符串
字符串就是字母的序列表示文本信息。
字符串的值用引號括起來,如下所示。
字符串是不可改變的,一旦創建,就不能被修改。如下所示:
當字符串變量被賦予一個新值時,Python 將創建一個新的目標來存儲這個變量值。
局部變量和全局變量
局部變量
局部變量,如在一個函數內聲明一個變量,則該變量只存在於該函數中。
局部變量在外部是不能被訪問的,如下所示。
Python 中 if-else 和 for/while 循環模塊是不能創建局部變量,如下所示在 for/while 循環中:
輸出為:
在 if-else 模塊中:
輸出為
全部變量
- 全局變量可以通過任意一個全局函數訪問,它們存在於 __main__ 框架中。
- 此外,在函數之外你也可以聲明一個全局變量。值得注意得是,當需要為一個全局變量分配新值時,必須使用“global”關鍵字,如下所示:
當移除“Global TestMode”只能在 some_function() 函數中將變量設置為 False。如果你想在多個模塊間共享一個全局變量,那么你需要創建一個共享模塊文件。如 configuration.py,並在文件中找到你所需的變量。最后導入共享模塊。
查看變量類型
- 通過 type() 函數來查看變臉類型,如下所示。
整型變量中的逗號
- 逗號可視為是變量序列,如下所示。
03、操作
數值操作
Python 支持基礎的加減乘除數值計算,也支持地板除法 (floor division),如下所示。
此外,Python 還支持指數運算 (**),如下所示。
同時,Python 還能進行除法取余操作,如下所示。
字符串操作
字符串拼接
字符串復制
字符串切片
字符串反序
負索引
如果你想得到字符串的最后一個字符,那需要使用負索引值,如下所示。
查看索引值
正則表達式
- split():通過正則表達式將一個字符串分割得到一個列表。
- sub():通過正則表達式取代所要匹配的字符。
- subn():通過正則表達式取代所要匹配的字符並返回所替代字符的個數。
Casting
- str(x):將變量 x 轉為字符串類型
- int(x):將變量 x 轉為整型
- float(x):將變量 x 轉為浮點型
集合操作
- 集合是一種無序的數據集合,定義一個集合變量,如下所示。
集合交集
- 獲取兩個集合的公共部分,如下所示。
集合差異
- 獲取兩個集合之間的不同部分,如下所示。
集合並集
- 獲取兩個集合的並集,如下所示。
三元運算符
- 用於在一行編寫條件語句,語法結構為 [If True] if [Expression] Else [If False],如下所示。
04、注釋
單行注釋
多行注釋
05、表達式
可用於布爾運算,如:
- Equality:==
- Not Equality:!=
- Greater:>
- Less:<
- Greater or Equal:>=
- Less or Equal:<=
06、Pickling
將對象轉換為字符串並將字符串轉儲為一個文件的過程稱為 pickling,反之則稱為 unpickling。
07、函數
- 函數是一種可以在代碼中執行的語句序列。如果在你的代碼中出現重復的語句,那么可以創建一個可重用的函數並在程序中使用它。
- 函數也可以引用其他函數。
- 函數消除了代碼中的重復,這使得代碼調試和問題查找變得更容易。
- 函數使得代碼更易於理解且易於管理。
- 函數允許將一個大型的應用程序拆分為一些小的模塊。
定義一個新的函數
調用一個函數
查看字符串的長度
可以調用函數 len(x),如下所示。
參數
參數可以被添加到一個函數中,使得函數更通用。
通過參數,可以將一個變量傳遞給方法,如下所示。
可選參數
為參數提供一個默認值來傳遞一個可選參數,如下所示。
* 參數
如果想讓函數使用任意數量的參數,那么需要在參數名前添加 *,如下所示。
** 參數
** 允許傳遞可變數量的關鍵字參數給函數,同時也可以傳遞一個字典值作為關鍵字參數。
Return
函數能夠返回一個值,如下所示。
如果一個函數需要返回多個值的話,那么最好返回一個元組 (以逗號隔開每個值),如下所示。
Lambda 函數
- 是一種單行表達式的匿名函數
- 是一種內聯函數
- Lambda 函數沒有聲明,只是通過一個表達式來實現,如下所示。
函數的語法結構為:variable = lambda arguments: expression
Lambda 函數也可以作為參數傳遞給其他的函數。
dir() 和 help()
- dir() 用於顯示定義的符號
- help() 用於顯示幫助文檔
08、模塊
什么是模塊
- Python 語言附帶了200多個標准模塊。
- 模塊是一種將 python 程序中相似功能進行分組的組件。
- 任何 python 代碼文件都可以打包為模塊,然后再導入。
- 模塊允許使用者在自己的代碼解決方案中進行組件化設計。
- 模塊提供了命名空間的概念,幫助使用者共享數據和服務。
- 模塊鼓勵代碼重用,並減少變量名稱沖突。
PYTHONPATH
- 這是 python 的環境變量,表示用於操作模塊的 python 解釋器所在的位置。PYTHONHOME 是一個用於搜索該路徑的模塊。
如何導入模塊
如果你有一個文件:MyFirstPythonFile 包含很多個函數,變量和對象,然后你可以將這些功能導入到其他類中,如下所示。
Python 內部會將模塊文件編譯為二進制再運行模塊的代碼
如果想導入模塊中的所有對象,可以這樣:
如果模塊中包含的函數或對象命名為 my_object,那么你可以將其打印出來,如下所示。
值得注意的是,如果你不想在加載時執行模塊的話,那么你需要檢查是否有 __name__ == ‘__main__’
From 導入模塊
如果你只是想訪問模塊中的一個對象或某個部分,可以這樣:
這種方式導入模塊允許使用者在訪問模塊中的對象,而無需引用模塊,如下所示。
可以通過 from * 來導入模塊中的所有對象,如下所示。
值得注意的是,模塊只能在第一次 import 時導入。如果你想使用 C 模塊,那么你可以使用 PyImport_ImportModule。此外,如果你想在兩個不同模塊中使用定義相同的對象,那么可以將 import 和 from 結合起來導入模塊。
09、包 (Packages)
Python 中包是模塊的目錄。
如果你的 Python 代碼中提供了大量功能,這些功能被分組到模塊文件中,那么可以從模塊中創建一個包,以便更好地分配和管理這些模塊。
包能夠更好地管理和組織模塊,這有助於使用者更輕松地解決問題和查找模塊。
可以將第三方軟件包導入到代碼中,如 pandas/scikit learn 和 tensorflow等等。
包可以包含大量的模塊。
如果代碼中的某些部分提供相似的功能,那么可以將模塊分組到一個包中,如下所示。
上圖中 packageroot 是一個根目錄 (root folder),packagefolder 是其根目錄下面的一個子目錄,而 my_module 是在 packagefolder 目錄下的一個 python 模塊文件。
此外,文件夾名可以作為命名空間,如下所示。
值得注意的是,需要確保所導入的包中每個目錄都包含一個 __init__.py 文件。
PIP
- PIP 是 python 的包管理器。
- 可以使用 PIP 來下載包,如下所示。
10、條件語句
條件語句 if else,如下所示。
請注意冒號和縮進在條件語句中的使用。
檢查類型
你也可以在 else 部分繼續添加條件邏輯語句,這樣構成嵌套條件結構,如下所示。
11、循環
While
While 語句提供一個條件,運行循環語句直到滿足該條件位置,循環終止,如下所示。
For
循環一定的次數,如下所示。
循環遍歷整個字符串的所有字符,如下所示。
單行 for 循環
語法結構為 [Variable] AggregateFunction ([Value] for [item] in [collection])
Yielding
- 假定你的列表中包含一萬億條數據,需要從列表中計算偶數的數量。這時候將整個列表加載到內存中並不是最佳的做法,你可以通過列表來生成每個項。
- 使用 xrange 的循環結構
結合條件 if 的 for 循環
通過帶 if 的 for 循環來查找兩個單詞中的字母,如下所示。
Break
如果你想終止循環,可以這樣:
使用 Fibonacci 函數的循環結構,如下所示。
12、遞歸
函數調用自身的過程稱為遞歸。
下面來演示一個階乘遞歸函數:
創建一個階乘函數,輸入為 n
如果輸入 n=0,則0! = 1
如果輸入 n != 0,則n! = n(n-1)!
此外,Fibonacci 遞歸函數的流程如下所示:
創建一個 Fibonacci 遞歸函數,輸入為 n
創建前兩個變量,並為其分別賦值0和1
如果輸入 n = 0,則返回0;如果輸入 n =1,則返回1;否則,返回 (n-1)+(n-2)
值得注意的是,遞歸結構需要有一個退出檢查,否則函數將進行無限循環。
13、框架 Frames 和棧 Stack 調用
Python 代碼被加載到堆棧中的框架。
函數及其參數和變量一起被加載到框架中。
框架以正確的執行順序被加載到堆棧中。
堆棧描述了函數的執行。在函數外聲明的變量被存儲在 __main__ 中。
堆棧首先執行最后一個框架。
如果遇到運行錯誤,可以使用回溯 (traceback) 來查找函數列表。
14、集合 Collections
列表 Lists
列表是一種能夠包含任何數據類型的序列數據結構,這種結構是可變的。
列表可以進行整數索引,可以使用中括號來創建一個列表,如下所示。
使用索引值來添加、更新、刪除列表中的項,如下所示。
此外,復制和切片同樣適用於列表 (可類比字符串中的操作), 列表還支持排序操作,如下所示。
元組 Tuples
在某種程度上元組和列表類似,都是可以存儲任意對象序列的數據結構。
元組的運行比列表更快速。
元組可以進行整數索引
元組是不可變的,如下所示。
值得注意的是,如果一個元組中的元素包含一個列表,那么可以對列表進行修改。同樣,當為一個對象賦值並將該對象存儲到列表中,隨后如果對象發生變化的話,相應地,列表中的對象也會進行更新。
字典 Dictionaries
字典是編程語言中最重要的一種數據結構之一,它能夠存儲鍵值對 (key/value) 對象。
字典有許多優點,能夠輕松地進行數據檢索,如下所示。
可以通過如下方式創建一個字典。
打印字典中的內容,如下所示。
字典中的值可以是任意類型的數據,包括字符串,數值,布爾型,列表甚至是字典,如下所示。
值得注意的是,如果你想對一個列表進行向量或矩陣操作,可以調用 Numpy 包來實現。
15、編譯 (Compilation) 與關聯 (Linking)
- 這些特征可用於一些以其他語言編寫的文件,例如 C 或 C++ 等。
- 一旦將代碼寫入文件后,可以將文件放在 Modules 目錄中。
- 在 Setup.local 文件中添加一行是非常重要的,這能確保新創建的文件能夠被加載。
編譯 Compilation
允許無任何錯誤地進行新擴展的編譯過程。
關聯 Linking
一旦新的擴展編譯完成,他們之間就會被關聯。
16、迭代器 Iterators
Iterators
- 允許遍歷一個集合
- 所有迭代器都包含 __iter __() 和 __next __() 函數
- 只需在列表,字典,字符串或集合上執行 iter(x) 即可
- 可以執行實例 next(iter),這里 iter = iter(list)
- 如果集合中元素項的數目非常大且無法一次加載內存中的所有文件,此時迭代器很有用
- 有一些通用的迭代器使開發人員能夠實現函數式編程,如下:
Filter
- 根據條件過濾掉相應的值
Map
- 對集合中的每個值進行計算,即將值進行映射,如將文本轉為整型數值。
Reduce
- 減少集合中的值,即得到一個更小的集合。如集合求和,它本質上是可迭代的。
Zip
- 獲取多個集合並返回一個新集合
- 新集合的每個項,包含每個輸入集合中的元素
- Zip 允許同時對多個集合進行橫向操作,如下所示。
17、面向對象設計——類 Classes
- Python 允許創建自定義類型,將這些用戶自定義的類型稱為類。這些類具有自定義屬性和功能。
- 面向對象的設計允許程序員根據自身所需的屬性和功能自定義創建對象。
- 屬性也可以引用另一個對象。
- Python 中的類可以引用其他類。
- Python 支持封裝 -- 實例函數和變量。
- Python 支持繼承,如下所示。
- 類的一個實例稱為對象。對象具有可變性,一旦創建對象,相應的屬性也將被更新。
__init__
- __init__ 函數在所有類中都存在。當需要進行類實例化時,該函數就將被執行。__init__ 函數可以根據需要設置相應的屬性,如下所示。
值得注意的是,self 參數將包含對象的引用,這與 C# 語言中的 this 參數類似。
__str__
當調用 print 時,返回一個對象的字符串結果,如下所示。
因此,當執行 print 語句時,__str__ 將會被執行。
__cmp__
如果想要提供自定義邏輯來比較同一實例的兩個對象,可以使用__cmp__ 實例函數。
__cmp__ 函數返回1 (更大), - 1 (更低) 和0 (相等),以指示兩個對象的大小。
可以將 __cmp__ 想象成其他編程語言中的 Equals() 方法。
Overloading
通過將更多參數作為實例,來重載一個對象。
還可以通過為 __add__ 來實現想要的運算符,如 +。
對象的淺拷貝 (Shallow Copy) 和深拷貝 (Deep Copy)
等效對象 – 包含相同的值
相同對象 – 引用相同的對象 – 內存中指向相同的地址
如果要復制整個對象,可以使用復制模塊 (copy module),如下所示。
這將導致淺拷貝,因為屬性的引用指針將會被復制。
如果對象的一個屬性是對象引用,那么它將簡單地指向與原始對象相同的引用地址。
更新源對象中的屬性將導致目標對象中的屬性也會更新。
淺拷貝是復制引用指針。
這種情況下可以利用深拷貝,如下所示。
如果 MyClass 包含引用 MyOtherClass 對象的屬性,則屬性的內容將通過 deepcopy 復制到新創建的對象中。
深拷貝將對對象進行新的引用。
18、面向對象設計——繼承
Python支持對象的繼承,即對象可以繼承其父類的功能和屬性。
繼承的類可以在其函數中包含不同的邏輯。
如果一個父類 ParentClass 有兩個子類 SubClass1 和 SubClass2,那么你可以使用Python來創建類,如下所示。
上例中兩個子類都將包含 my_function() 函數
類的繼承屬性鼓勵代碼的重用性和可維護性。
此外,python 中支持多類繼承,這與 C# 語言不同。
多類繼承 multi-Inheritance
如果你想調用父類函數,可以這樣:
19、垃圾收集——內存管理
Python 中的所有對象都存儲在一個堆積空間 (heap space),而 Python 解釋器可以訪問此空間。
Python 有一個內置的垃圾收集機制。
這意味着 Python 可以自動為程序進行分配和取消內存,這與 C++ 或 C# 等其他語言類似。
垃圾收集機制主要是清除程序中未引用/使用的那些對象的內存空間。
由於多個對象可以共享內存引用,因此 python 使用兩種機制:
- 引用計數:計算引用對象的數目。如果對象的計數為0,則取消對象的空間分配。
- 循環引用:這種機制關注的是循環引用:當取消分配 (deallocation) 的數目大於閾值時,僅取消對象所在的內存空間分配。
在 Python 中新創建的對象,可以通過如下方式進行檢查:
此外,也可以通過及時或者基於事件機制來進行手動的垃圾收集。
20、 I/O
From Keyboard
使用 raw_input() 函數,如下所示。
文件 Files
使用with/as語句來打開並讀取文件,這與 C# 中讀取文件的操作一致。
此外,with 語句還可以處理關閉連接和其他清理操作。
打開一個文件,如下所示。
需要注意的是,readline() 可用於讀取文件中的每一行。
打開兩個文件,如下所示。
文件寫入,如下所示。
Python 中對文件的操作通常涉及 os 和 shutil 模塊。rw 表示讀寫模式,a代表可添加模式。
SQL
打開一個連接,如下所示。
執行一個 SQL 聲明,如下所示。
網絡服務 (Web Services)
查詢一個閑置服務,如下所示:
序列化和反序列化 JSON 文件
反序列化 JSON,如下所示:
序列化 JSON,如下所示:
21、異常處理
拋出異常
如果你想拋出異常,那么可以使用 raise 關鍵字,如下所示。
捕獲異常
可以通過如下方式捕獲異常信息:
如果想捕獲特定的異常,可以這樣:
如果想使用 try/catch/finally 結構捕獲異常信息,可以這樣:
值得注意的是,無論 finally 部分的代碼是否觸發,你都可以使用 finally 來關閉數據庫/文件的連接。
Try/Except/Else
如果想為異常信息分配一個變量,可以這樣:
如果想定義用於自定義的限制,可以通過 assert 關鍵字實現,如下所示:
值得注意的是,python 中的異常同樣具有繼承性。
此外,你也可以創建自己的異常類,如下所示:
22、多線程和 GIL
- GIL 表示 Global Interpreter Lock。
- GIL 確保線程可以在任何時間執行,並允許 CPU 選擇要執行的所需線程。
- GIL 能夠傳遞當前正在執行的線程。
- Python 支持多線程。
此外,GIL 會增加代碼執行的計算開銷。因此,運行多線程時需謹慎。
23、裝飾器 Decorators
- 裝飾器可以為代碼添加功能,其本質上是一種調用其他對象/函數的函數。 它是可調用函數,因此在調用裝飾器函數時將返回隨后需要調用的對象。
- 通過封裝包/裝一個類/函數,然后在調用函數時執行特定的代碼。
- 此外,還可以通過實現通用邏輯來記錄,進行安全檢查等,然后使用 property 標記方法的屬性。
24、Python 中的單元測試
Python 中有許多單元測試和模擬庫
下面以 unittest 為例
假定你的函數每次將輸入值減少1,如下所示:
可以通過如下方式來進行單元測試:
同樣地,也可以使用 doctest 來測試 docstrings 中所編寫的代碼。
25、一些與 Python 有關的熱門話題
為什么要使用 Python
- 編碼簡單,易於學習
- 面向對象編程語言
- 強大的分析功能和機器學習包
- 更快速地開發並將解決方案推向市場
- 提供內置的內存管理功能
- 提供巨大的社區支持和應用程序
- 無需編譯,因為它本身是一種可解釋的語言
- 動態輸入,即無需聲明變量
如何讓 Python 運行得更快
- Python 是一種高級語言,不適合在系統程序或硬件層面訪問。
- Python 不適用於跨平台的應用程序。
- Python 是一種動態類型的解釋語言。與低級語言相比,它的優化和運行速度較慢。
- 實現基於 C 語言的擴展。
- 可以使用 Spark 或 Hadoop 創建多進程
- 可以利用 Cython,Numba 和 PyPy 來加速 Python 代碼或用 C 語言編寫它並在 Python 中公開。
Python 愛好者都是用哪些 IDEs?
- 包括 Spyder,Pycharm 等。此外,還會使用各種的 notebooks,如 Jupyter。
Python 中熱門的框架和包有哪些
- Python 中必須掌握的包有很多,包括 PyUnit (單元測試), PyDoc (文檔), SciPy (代數和數值計算), Pandas (數據管理), Sci-Kit learn (機器學習和數據科學), Tensorflow (人工智能), Numpy (數組和數值計算), BeautifulSoap (網頁爬取), Flask (微服務框架), Pyramid (企業應用), Django (UI MVVM), urllib (網頁爬取), Tkinter (GUI), mock (模擬庫), PyChecker (bug 檢測器), Pylint (模塊代碼分析) 等。
如何托管 Python 包
對於 Unix 系統:制作腳本文件,模式為可執行且文件第一行必須是:
可以使用命令行工具並執行它。也可以通過 PyPRI 和 PyPI 服務。
Python 和 R 語言能合並嗎
R 語言中有着大量豐富的統計庫,可以使用 Rpy2 python 包或在 Juputer 中使用 beaker 筆記本或 IR 內核,在 Python 中執行 R 代碼。
在運行 Python 前有沒有辦法能夠捕獲異常?
在運行代碼之前,可以使用 PyChecker 和 PyLink 來捕獲異常信息。
總結
本文概述了 Python 最重要的25個概念,這些知識對初學者來說足以編寫自己的 Python 包或使用現有的 Python 包,希望能幫助大家更好地學習 Python。
本文分享自華為雲社區《Python從入門到精通25個關鍵技術點》,原文作者:簡單堅持。