前言
為什么想起學Python了?
之所以想起學學Python是有三個緣由。從時間順序上看,首先是在10月中旬,筆者去學校招聘會走了走,發現招Python開發的挺多的,有在線教育、智慧城市等行業,基本以數據挖掘處理為主。其次是10月中旬接到了騰訊微信搜一搜后台的實習面試邀請,那邊招C++和Python開發,用的是騰訊自研框架。最后也是最重要的,在11月上旬,筆者參加的電子設計大賽F題送葯小車核心點在圖像識別,而市面上用的比較多的OpenMV需要用Python開發。這讓筆者意識到是時候該學學Python了,雖然說學好一門語言后再學第二門會很簡單,但萬一遇到緊急項目,總不能再花時間在語法基礎上吧,項目所需要的框架也是需要學習成本的。
Python與Java?
筆者對Java比較熟練,也是以Java作為第一門語言開始學習的。有了一定開發經驗后最大的感受是確實能快速上手Python,特別是面向對象那塊,畢竟編程思想是可以互通的。至於以后會不會從事Python相關的開發工作,要看市場和項目需求,現階段還是會以Java的學習為重,筆者Java還有好多好多要學的呢,Python暫時學來玩玩刷刷leetcode就好了。
參考資料:
筆者Python學習主要以《Python編程:從入門到實戰》這本書為主,筆記的思路參考書里的脈絡。其次還有筆者一年前在慕課上看的北理的嵩天教授的Python課程。嵩天教授的課很好,最大的特點是每個版塊都有完整的示例代碼。但可能對新手小白不太友好,有些不常用的函數容易弄混。《Python編程:從入門到實戰》更適合零基礎學習,里邊會提到一些互通的編程思想和Python的格式規范。
結合常用函數、方法:
由於筆者有Java的編程基礎,因此這里只記錄Python跟Java不一樣的地方以及一些易忘點和難點,重點放在Python的語法基礎。對於新手朋友還是先看書為好。結合《Python常用函數、方法示例總結(API)》來看可能效果會好一些。
1. 變量與簡單數據結構
-
.py指出這是一個Python程序,編輯器將使用Python解釋器運行它; -
Python解釋器讀取整個程序,確定其中每個單詞含義;
-
程序無法成功運行時,解釋器會提供一個
traceback。traceback是一條記錄,指出解釋器嘗試運行代碼時,在什么地方陷入困境; -
在Python中,可以用單引號或雙引號括起字符串;
-
Python中的轉義符:
\n換行(光標到下行首);\r回車(光標回到本行首);\t制表符,\n\t表示換行並在下一行開頭添加制表符;\b回退;
-
Python2中,有些
print語句包含括號,有些不包含; -
Python使用兩個乘號表示乘方,如:
3 ** 2 == 9; -
Python2中除法
\將小數部分直接刪除。Python3中保留小數。但在Python2中:3.0 / 2 == 1.5; -
Python之禪:Python的一些編程理念。在終端輸入
import this即可獲取; -
Python關鍵字:

-
Python內置函數:


2. 列表相關
- 一個列表示例:
bicycles = [ 'trek', 'cannondale', 'redline']。注意方括號與逗號; - 打印列表示例:
print(bicycles); - 訪問列表元素:
bicycles[0]--- > trek; - 訪問列表倒數第x元素:
bicycles[-x]--- > 當x=1時輸出:redline; - 使用for循環遍歷列表:
for object in list: print(object) - 列表解析:
list = [num**2 for num in range(1s, 11)]---> 輸出1到10的平方; - 遍歷部分列表:
for object in list[firstNum: lastNum]:; - 可以使用
list[:]的方法復制列表; - 元祖相關:
- Python中將不能修改的值稱為不可變的,而不可變的列表稱為元祖;
- 在編程上與列表不同之處在於其使用
()或tuple()或不使用括號;而列表使用[]或list(); - 元組因為創建后不能修改,因此沒有特殊操作;
- 如果提出修改Python語言修改建議,需要編寫Python改進提案(PEP)。PEP 8是最古老的PEP之一,其規定了以下一些Python代碼格式規范:
- 每級縮進4個空格。需要對文本編輯器(或ide)設置tab鍵為4個空格;
- Python解釋器根據水平縮進解讀代碼,不關心垂直間距;
- 建議每行不超過個字符;
- 建議比較運算符兩邊各添加一個空格;
3. 集合
-
一個集合示例:
bicycles = { 'trek', 'cannondale', 'redline'}。注意大括號與逗號; -
集合的特點是不能重復;
-
利用集合數據去重:
s = set(list) #利用集合無重復元素的特點去重 l = list(s) #將集合轉變回列表
4. If語句
- Python在檢查是否相同時考慮大小寫;
- 大部分時候檢查兩個指不等的效率更高;
- 在Python中使用
and和or表示並與或,而不是&&和||; - 檢查列表是否含有特定值的語句:
if(object in list),也可以用if(object not in list); - Python的if語句基本結構如下(注意冒號):
if conditional_test1: do something1 elif conditional_test2: do something2 else: do other - 判斷列表是否為空:
if list:
5. 字典
- 事實上,可將任意Python對象用作字典中的值;
- 一個字典的示例:
alien0 = {'color': 'green', 'points': 5} - 遍歷字典:
for key, value in map.items(): - 遍歷字典的鍵:
for object in map.keys():或for object in map:,因為遍歷字典默認遍歷所有的鍵; - 按順序遍歷字典所有的鍵:
for object in sorted(map.keys()): - 遍歷字典的值:
for object in map.values(): - 遍歷字典的值,剔除重復項:
for object in set(map.values()): - 列表和字典的嵌套層級不應太多,如果太多,可能有更簡單的解決問題的方案;
6. 用戶輸入和while循環
- 在Python 3里使用
input()方法,而在Python 2.7里使用raw_input()方法; - 循環語句:
while conditional_test: - 可以使用
break關鍵字退出循環,這里的循環包括while和for循環; - 可以使用
continue關鍵字繼續循環; - 使用循環處理列表:
while object in list:
7. 函數
-
不帶返回值的函數定義示例:
def greet_user(username, age=1): #username沒有設定默認值必須放在形參列表開頭 """顯示簡單問候語""" print("hello, " + username.title() + ", age is " + str(age)) greet_user('jesse', 18) #位置實參 greet_user(age=18, username='jesse') #關鍵字實參 greet_user('jesse') #使用默認值age=1- 第二行為文檔字符串注釋,描述函數是做什么的;
- 后面為函數調用;
-
帶普通返回值的函數定義示例:
def greet_user(username, age=1): #username沒有設定默認值必須放在形參列表開頭 """顯示簡單問候語""" print("hello, " + username.title() + ", age is " + str(age)) return username.title() -
帶字典返回值的函數定義示例:
def build_person(first_name, last_name): #username沒有設定默認值必須放在形參列表開頭 """返回字典""" person = {'first': first_name, 'last': last_name} return person -
傳遞列表參數,列表會修改:
def greet_users(names): """傳入參數為列表""" for name in names: msg = "Hello, " + name.title() + "!" print(mas) usermanes = ['margot', 'hannah', 'ty'] greet_users(usernames) -
傳遞列表參數的副本,列表不會修改:
def greet_users(names[:]): -
傳遞任意數量的實參:*toppings可以理解成列表;
def make_pizza(*toppings): """打印顧客點的所有配料""" print(toppings) make_pizza('pepperoni') make_pizza('mushrooms', 'green peppers', 'etra cheese')- Python創建一個名為toppings的空元組;
-
結合使用位置實參和任意數量實參:
def make_pizza(size, *toppings):- 必須將接納任意數量實參的形參
*toppings放在最后;
- 必須將接納任意數量實參的形參
-
使用任意數量的關鍵字實參:**user_info可以理解成字典;
def build_profile(name, **user_info): """創建一個字典,其中包含我們知道的有關用戶的一切""" profile = {} profile['name'] = name for key, value in user_info.items(): profile[key] = value return profile user_profile = build_profile('albert', location='princeton', field='physics') print(user_profile) -
在Python中,import的是模塊,使用模塊.方法(參數)即可調用模塊里的函數;
-
導入特定函數,並使用該函數示例:
from module_name import function_0, function_1 function_0() function_1(參數) -
使用
as給函數指定別名:from model import function as fn;后續使用fn()即可調用function函數; -
使用
as給模塊指定別名:import model as md;后續使用md.function()即可調用函數; -
導入模塊所有函數:
from model import *;后續直接使用model里的函數function()即可調用函數; -
可以在函數類使用
global關鍵字聲明變量是全局變量; -
lambda表達式:
<函數名> = lambda <參數> : <表達式>;- 示例:
>>> f = lambda x, y : x + y >>> f(10, 15) 25 >>> f = lambda : "lambda表達式" >>> print(f()) lambda表達式 -
函數與模塊編寫細節:
- 外部函數導入的推薦做法:只導入所需要使用的函數 / 導入整個模塊並使用句點表示法;
- 函數和模塊的命名應使用小寫字母和下划線,而不是駝峰命名法;
- 函數注釋緊跟在函數定義后面,使用文檔字符串格式;
- 給形參指定默認值時,等號=兩邊不要有空格;
8. 類與對象
-
類中的函數叫方法;
-
一個類示例:模塊名為
dog.py"""表示小狗和電子狗的類""" class Dog(): """模擬小狗""" def __init__(self, name): """初始化實例""" self.name = name self.age = 1 #給屬性指定默認值 def get_age(self): """返回年齡""" return self.age def set_age(self, age): """設置年齡""" self.age = age def sit(self): """模擬小狗被命令時蹲下""" print(self.name.title() + " is now sitting.") class TinyDog(Dog): """小狗是狗的子類""" def __init__(self, name) """初始化父類的屬性""" super().__init__(name)__init__()方法:形參self必不可少,而且必須位與其他參數前面;- 創建Dog實例時,將自動傳入實參self。每個與類相關聯的方法調用都自動傳遞實參self,其是一個指向實例本身的應用,讓實例能夠訪問類中的屬性和方法;
self.為前綴的變量都可供類中的所有方法使用,像這樣可以通過實例訪問的變量稱為屬性;
-
有關父子類:
- 子類和父類必須包含在當前文件中,父類必須在子類前面;
- 子類定義中括號內必須指定父類名稱;
super()是一個特殊函數,將父類和子類關聯起來;- 在Python 2.7中,
super()方法需要傳遞兩個實參:子類名和self,並且父類定義的括號內指定字段object;
-
在Python 2.7中創建類時,需要在括號類內包含單詞object:
class ClassName(object): -
類實例(對象)的示例:
class Dog(): --snip-- my_dog = Dog('willie') dog_name = my_dog.name #獲取屬性 dog_name = my_dog.get_age() #通過方法獲取屬性 my_dog.name = 'jucy' #直接修改屬性 my_dog.set_age = 18 #通過方法修改屬性 my_dog.sit() #調用方法 -
從dog.py模塊里導入多個類:
from dog import Dog, TinyDog; -
導入整個dog.py模塊,然后用句點表示訪問需要的類:
import dog; -
collections模塊里包含一個類
OrderedDict。該類的實例行為幾乎與字典相同,區別在於其記錄了鍵值對的順序; -
類的編碼風格:
- 類采用駝峰命名法,類中的每個單詞首字母大寫;
- 實例名和模塊名采用小寫,並在單詞之間加上下划線;
- 一個空行分隔方法;兩個空格分隔類;
- 需要同時導入標准庫和模塊和
9. 文件
-
打開並讀取一個文件,並將其內容顯示到屏幕上:
with open('xxx.txt') as file_object: contents = file_object.read() print(contents)- 打開文件
open()和關閉文件close()可以同時使用,但當有bug時close()執行不了會導致文件無法關閉。不寫close()將由Python確定是否關閉文件; with關鍵字在不再需要訪問文件后將其關閉;- 直接打印contents會多出一個空行,可以這樣打印
print(contens.rstrip());
- 打開文件
-
有關文件絕對路徑:
- Linux和OS X:
file_path = '/home/.../xxx.txt'; - Windows:
file_path = C:\...\xxx.txt; - 建議將數據文件存儲在程序文件所在的目錄,或程序文件所在目錄的下一級文件夾;
- Linux和OS X:
-
逐行讀取:
with open(filename) as file_object: for line in file_object: print(line)- 同理,直接打印contents會多出一個空行,可以這樣打印
print(line.rstrip());
- 同理,直接打印contents會多出一個空行,可以這樣打印
-
使用
with關鍵字時,open()返回的對象只在with代碼塊內可用; -
在處理文件相關時注意使用
strip()或rstrip()去除字符串兩邊的空格; -
Python將所有文本都解讀成字符串;
-
open('xxx.txt', 'w'):以寫入方式打開文件;- 其他參數還有
r讀取、a附加、r+讀寫; a附加:將內容附加到文件末尾,而不是覆蓋文件原來的內容;- 以
w寫入模式打開文件需要小心,如果指定文件名已存在,Python將在返回對象前清空文件; - Python只能將字符串寫入文本文件;
- 其他參數還有
10. 異常
-
使用 try-except 處理異常:
try: print(5/0) except ZeroDivisionError: print('捕獲到ZeroDivisionError異常') else: print('未捕獲異常') finally: print('無論是否有異常都會執行')- 可在
except的縮進塊里添加關鍵字pass跳過錯誤捕獲; - 其中,
else和finally部分的代碼塊可省;
- 可在
11. 測試
-
使用Python標准庫中的模塊
unittest進行測試; -
一個簡單的測試示例:
import unittest from model_name import function_name class TestCase(unittest.TestCase): """測試函數function_name""" def setUp(self): """構建前置條件""" def test_function(self): run_result = function_name(parameter) self.assertEqual(run_result, correct_result) unittest.main()- 首先導入模塊
unittest和被測試方法function_name; - 然后創建
TestCase類,其包含各種具體的單元測試方法。該類繼承unittest.TestCase類; setUp()方法的作用是創建前置條件;- 編寫測試方法
test_function,方法名必須以test_打頭; - 使用斷言
assertEqual()判斷函數執行結果與預期結果的差別; unittest.main()讓Python運行這個文件中的測試;
- 首先導入模塊
-
unittest里常用的6個斷言方法請見《Python常用函數、方法示例總結(API)》;
-
每完成一個測試,Python都會打印一個字符:
- 測試通過打印句點
.; - 測試引發錯誤打印一個
E; - 測試導致斷言失敗打印一個
F;
- 測試通過打印句點
最后
