1 課前甜點
- Python 代碼一般比 C 系語言短的緣由
- 高級數據類型容許在一個表達式中表示覆雜的操做
- 代碼塊的劃分是按照縮進
- 不須要預約義變量
2 使用 Python 解釋器
2.1 調用解釋器
- EOF unix C-d windows C-z
- 執行 Python 代碼 python -c command [arg]
- 把 Python 模塊當腳本使用 python -m module [arg]
- 執行腳本後進入交互模式 python -i 1.py
2.1.1 傳入參數
- sys.argv sys.argv[0] 是程序名
2.1.2 交互模式
2.2 解釋器的運行環境
2.2.1 源文件的字符編碼
- 默認編碼就是 utf-8 必須放在第一行或者 UNIX 「shebang」 後
3 Python 的非正式介紹
- 註釋 #
3.1 Python 做爲計算器使用
3.1.1 數字
- 除法 / 永遠返回浮點數類型 // floor division
- 乘方 **
- 交互模式下,上一次被執行顯示的表達式的值會被保存在 _
- Python 內置對複數的支持 3+5j
3.1.2 字符串
- 原始字符串
- 三重引號會自動包含換行,能夠在行尾加反斜槓防止換行
- 相鄰的兩個字符串字面值會自動鏈接到一塊兒
- 經過索引取得的單個字符是一個長度爲一的字符串
- 切片中越界索引會被自動處理
- Python 中字符串是不可修改的,若是須要一個不一樣的字符串,應當新建一個 a = 「heheda」 b = a[:-1] + 「b」
3.1.3 列表
- 列表的切片都返回一個新列表
- 列表支持使用 + 拼接其餘列表
-
能夠給列表切片賦值,這樣能夠改變列表大小,甚至清空整個列表python
a = [1, 2, 3, 4] a[1:3] = [4, 5] a[:] = []
3.2 走向編程的第一步
3.2.1 多重賦值
3.2.2 print
print 會在多個參數間加空格能夠傳入 end 參數指定結尾替換換行的字符串sql
4 其餘流程控制工具
4.1 if 語句
- 輸入 aa = input(「input: 」)
- if if elif else
4.2 for 語句
- Python 中的 for 是對任意序列進行迭代
-
若是在循環內須要修改序列中的值,推薦先拷貝一份副本shell
words = ['aaa', 'bbb', 'ccccccc'] for w in words[:]: if len(w) > 5: words.insert(0, w)
4.3 range() 函數
- range(0, 10, 3) 0, 3, 6, 9
-
以序列的索引迭代編程
a = ['a', 'b', 'c'] for i in range(len(a)): print(i, a[i]) for i, v in enumerate(a): print(i, v)
- range() 返回的不是列表,是一個可迭代對象
4.4 break 和 continue 語句,以及循環中的 else 子句
- else 子句 else 子句會在未執行 break,循環結束時執行
4.5 pass 語句
- pass 一般用於建立最小的類 class MyEmptyClass: pass
- pass 也用於寫代碼時做爲函數或條件子句體的佔位符,保持在更抽象的層次上思考
4.6 定義函數
- 文檔字符串
- 全局變量和外部函數的變量能夠被引用,可是不能在函數內部直接賦值
- 函數的重命名機制
- 沒有 return, 函數會返回 None
- 列表方法 append() 比 + 效率高
4.7 函數定義的更多形式
4.7.1 參數默認值
- in 測試一個序列是否包含某個值
- 默認值時在定義過程當中在函數定義處計算的,而不是調用時
-
默認值只執行一次,若是是可變對象,好比列表,就能夠在後續調用之間共享默認值相似於 c 中的靜態變量json
def f(a, L=[]): print(a) L.append(a) print(L) f(1) f(2) f(3) f(4)
4.7.2 關鍵字參數
- 關鍵字參數必須在位置參數後
- 形參 * **
4.7.3 任意的參數列表
- 任意的參數列表 *args 通常位於形式參數列表的末尾,只有關鍵字參數能出如今其後
4.7.4 解包參數列表
- 使用* 從列表或元組中解包參數 args = [3, 6] range(*args)
- 使用** 從字典解包參數
4.7.5 Lambda 表達式
-
閉包windows
def make_incrementor(n): return lambda x: x + n f = make_incrementor(33) f(0)
-
傳遞一個函數做爲參數api
pairs = [(1, 'one'), (2, 'two'), (3, 'three')] pairs.sort(key=lambda pair: pair[1])
4.7.6 文檔字符串
- 一些約定第一行簡要描述對像的目的,大寫字母開頭,句點結尾第二行空白,後面幾行是一個或多個段落,描述調用約定,反作用等
4.7.7 函數標註
-
標註不會對代碼有實質影響,只是給人看
def f(ham: str, eggs: str = "eggs") -> str: print(f.__annotations__) return ham + ' and ' + eggs
4.8 小插曲: 編碼風格
- 使用 4 空格縮進,而不是製表符
- 一行不超過 79 個字符(能夠在較大顯示器並排放置多個代碼文件)
- 使用空行分割函數和類,以及函數內的較大的代碼塊
- 儘可能把註釋放到單獨的一行
- 使用文檔字符串
- 在運算符先後和逗號後使用空格
- 函數和類命名應使用一致規則類 UpperCamelCase 函數 lowercasewithunderscores
- 通常不另外設置代碼的編碼
- 不要在標識符中使用非 ASCII 字符
5 數據結構
5.1 列表的更多特性
- 列表對象方法的清單 list.append(x) list.extend(iterable) list.insert(i, x) list.remove(x) list.pop([i]) list.clear() list.index(x[, start[, end]]) list.count(x) list.sort(key=None, reverse=False) list.reverse() list.copy()
5.1.1 列表做爲棧使用
- list.append(x) list.pop()
5.1.2 列表做爲隊列使用
-
在列表開頭插入或彈出元素很慢
from collections import deque queue = deque(['aaa', 'bbb', 'ccc']) queue.append('ddd') queue.popleft()
5.1.3 列表推導式
- for 循環後,循環變量還存在
- 列表推導式中,for 和 if 順序和展開形式的順序是一致的
- 若是表達式是一個元組,須要加括號
5.1.4 嵌套的列表推導式
a = [1, 2, 3] b = [4, 5, 6] print(list(zip(a, b)))
5.2 del 語句
- del 能夠刪除指定索引的元素
- del 能夠刪除切片指定的範圍
- del a[:]
- del a
5.3 元組和序列
- 元組一般包含不一樣種類的元素,列表的元素通常是同種類型
- 空元組能夠直接被一對圓括號建立
- 元組輸入時圓括號無關緊要
5.4 集合
- set()
- 集合操做 a | b a - b a & b a ^ b
- 集合推導式 a = {x for x in ’abcdedd’ if x not in ’abc’}
5.5 字典
- 只要不包含不可變對象,均可以做爲鍵
5.6 循環的技巧
- 字典循環時,能夠用 items() 方法把關鍵字和值同時取出
- 序列循環時,能夠用 enumerate()函數將索引和值同時取出
- 要同時在多個序列中循環時,能夠用 zip()函數
- 若是要逆向一個序列,可使用 reversed()函數
- sorted()函數能夠返回一個新的排好序的序列
- 在循環時想修改列表內容,最好建立新列表
5.7 深刻條件控制
- in 和 not in
- is 和 is not 比較是否是同一個對象
- 比較操做能夠傳遞
5.8 比較序列和其餘類型
- 序列也能夠比較
6 模塊
- 若是常用某個導入的函數,能夠賦值給一個局部變量重命名
6.1 更多有關模塊的信息
-
幾種導入方式
from fibo import fib, fib2 from fibo import * import fibo as fib from fibo import fib as fibonacci
- 每一個模塊在每一個解釋器會話中只被導入一次,若是更改了模塊,要從新啓動解釋器或 import importlib importlib.reload(module)
6.1.1 以腳本的方式執行模塊
- 若是直接執行腳本,_name__ 被賦值爲_main__
6.1.2 模塊搜索路徑
- 搜索路徑
- 內置模塊
- sys.path 給出的目錄列表
- 包含輸入腳本的目錄
- PYTHONPATH
- 取決於安裝的默認設置
6.1.3 「編譯過的」Python 文件
- python3 會把 pyc 統一放在_pycache_下 python2 是放在源文件同目錄下
- pyc 和 py 文件運行速度是同樣的,只是 pyc 的載入速度更快
6.2 標準模塊
- sys.ps1 sys.ps2 用於定義交互模式下的提示符
6.3 dir() 函數
- dir 用於查找模塊定義的名稱
- 若是沒有參數,dir 會列出當前定義的名稱
- dir 不會列出內置函數和變量,他們定義在標準模塊 builtins
6.4 包
- 包是一種經過用「帶點號的模塊名」來構造 Python 模塊命名空間的方法
- _init_.py 中能夠執行包的初始化代碼或設置_all__ 變量
- 一些導入方式
- 導入模塊 import a.b.c 使用時要使用全名 from a.b import c 能夠直接用 c from a.b.c import d 能夠直接用 d
6.4.1 從包中導入*
- 導入一個包時會參考它 init.py 內_all__ 列表的內容
6.4.2 子包參考
- 相對導入 from . improt echo from .. import formats from ..filters import equalizer
- 相對導入時基於當前模塊的名稱進行導入的,因此主模塊必須用絕對導入
6.4.3 多個目錄中的包
7 輸入輸出
7.1 更漂亮的輸出格式
- 一些格式化輸出方式 aa = ’a test’ b = f’hehe {aa}’ ’{gg}’.format(aa)
- str() 返回人類可讀的值的表示
- repr() 生成解釋器可讀的表示
7.1.1 格式化字符串文字
- 一些示例 print(f’value {math.pi:.3f}.’) print(f’{name:10} {num:10d}’) print(f’{animal!r}’) # !a ascii() !s str() !r repr()
7.1.2 字符串的 format() 方法
7.1.3 手動格式化字符串
- rjust() ljust() center()
7.1.4 舊的字符串格式化方法
- %
7.2 讀寫文件
- 最好使用 with
7.2.1 文件對象的方法
- 經常使用方法列表 f.read() f.readline() f.write() f.tell() f.seek(5) f.seek(-3,2) # 0 start 1 current 2 end
- 遍歷行 for line in f: pass
7.2.2 使用 json 保存結構化數據
- 經常使用方法 jons.dumps([1, ’a’, 2]) json.dump(x, f) x = json.load(f)
8 錯誤和異常
8.1 語法錯誤
8.2 異常
8.3 處理異常
- else 子句必須放在 except 後
8.4 拋出異常
- 在 except 處理時能夠 raise 拋出異常
8.5 用戶自定義異常
- 自定義異常通常只是提供一些屬性
8.6 定義清理操做
- finally 子句
8.7 預約義的清理操做
- with 語句
9 類
9.1 名稱和對象
- Python 中,多個變量能夠綁定到一個對象,對於可變對象,表現得相似於指針
9.2 Python 做用域和命名空間
9.2.1 做用域和命名空間示例
-
關於 nonlocal global 的用法
def do_local(): spam = "local spam" def do_nonlocal(): nonlocal spam spam = "nonlocal spam" def do_global(): global spam spam = "global spam" spam = "test spam" do_local() print("After local assignment:", spam) do_nonlocal() print("After nonlocal assignment:", spam) do_global() print("After global assignment:", spam) scope_test() print("In global scope:", spam)
輸出結果 After local assignment: test spam After nonlocal assignment: nonlocal spam After global assignment: nonlocal spam In global scope: global spam
9.3 初探類
9.3.1 類定義語法
9.3.2 類對象
- 類對象支持兩種操做: 屬性引用和實例化
- _doc__ 文檔字符串
9.3.3 實例對象
- 實例對象的惟一操做是屬性引用
- 兩種屬性名稱: 數據屬性和方法
- 數據屬性不須要聲明,在第一次賦值時產生
9.3.4 方法對象
-
區分方法對象和函數對象
class TestClass: def kk(self): print('aaa') bb = TestClass() bb.kk() TestClass.kk(bb)
9.3.5 類和實例變量
9.4 補充說明
9.5 繼承
- isinstance(obj, int)
- issubclass(bool, int)
9.5.1 多重繼承
- 搜索的順序是深度優先,從左到右
9.6 私有變量
- 經過約定,下劃線開頭的名稱
9.7 雜項說明
-
定義空類,簡單實現將命名數據捆綁在一塊兒
class Employee: pass johb = Employee() john.name = "peter" john.dept = "computer lab"
- 實例方法對象具備的屬性 m._self__ 帶有 m 方法的實例對象 m._func__ 該方法對應的函數對象
9.8 迭代器
- for 的機制
- for 會用 iter() 函數調用容器內的_iter_()方法
- 此方法會返回一個定義了_next_()方法的對象
- 調用 next() 函數,會調用上一步返回對象的_next_()方法
- 當元素用盡時,_next_()會引起 StopIteration 異常
- 給本身的類添加迭代器行爲
- 定義_iter__ 方法,返回 self
-
定義_next__ 方法,返回一個改變引用所指的對象,同時設置條件,遍歷完 raise StopIteration
class Reverse: def __init__(self, data): self.data = data self.index = len(data) def __iter__(self): return self def __next__(self): if self.index == 0: raise StopIteration self.index = self.index - 1 return self.data[self.index]
9.9 生成器
- 寫法相似標準函數,可是返回不用 return,用 yield
- 生成器會自動建立_iter_()和_next_(),生成器終結時會自動引起 StopIteration
9.10 生成器表達式
- 生成器表達式被設計用於生成器將當即被外層函數所使用的狀況 sum(i*i for i in range(10))
10 標準庫簡介
10.1 操做系統接口
- import os os.getcwd() os.chdir() os.system
- 對於平常文件和目錄管理任務,shutil 模塊提供了更易於使用的更高級模塊 shutil.copyfile() shutil.move()
10.2 文件通配符
- import glob 提供了在一個目錄中使用通配符搜索文件列表的函數 glob.glob(’*.py’)
10.3 命令行參數
- import sys print(sys.argv)
-
argparse
import argparse from getpass import getuser parser = argparse.ArgumentParser(description='An argparse example.') parser.add_argument('name', nargs='?', default=getuser(), help='The name of someone to greet.') parser.add_argument('--verbose', '-v', action='count') args = parser.parse_args() greeting = ["Hi", "Hello", "Greetings! its very nice to meet you"][args.verbose % 3] print(f'{greeting}, {args.name}') if not args.verbose: print('Try running this again with multiple "-v" flags!')
10.4 錯誤輸出重定向和程序終止
- sys.std sys.stdin sys.stdout sys.stderr.write(’wrong’)
- 終止腳本 sys.exit()
10.5 字符串模式匹配
- import re re.findall(r’\bf[a-z]*’, ’which foot or hand fell fastest’) re.sub(r’(\b[a-z]+) \1’, r’\1’, ’cat in the the hat’) ’cat in the hat’
- 當只須要簡單的功能時,首選字符串方法
10.6 數學
- math 提供了對浮點數的低層 C 庫函數的訪問
- import math math.cos(math.pi / 4) math.log(1024, 2)
- random random.choice([’a’, ’b’, ’c’]) random.sample(range(100), 10) # 選 10 個樣本出來 random.random() # 0 到 1 的隨機數 random.randrange(5) # 從 range(5) 選
- import statistics statistics.mean() # 平均值 statistics.median() # 中位數 statistics.variance() # 方差
10.7 互聯網訪問
-
urllib.request
from urllib.request import urlopen with urlopen('http://www.baidu.com') as response: for line in response: line = line.decode('utf-8') if 'EST' in line or 'EDT' in line: print(line)
-
smtplib
import smtplib server = smtplib.SMTP('localhost') server.sendmail('soothsayer@example.org', 'jcaesar@example.org', """To: jcaesar@example.org From: soothsayer@example.org Beware the Ides of March. """) server.quit()
10.8 日期和時間
-
datetime
# dates are easily constructed and formatted from datetime import date now = date.today() now # datetime.date(2003, 12, 2) now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.") # '12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.' # dates support calendar arithmetic birthday = date(1964, 7, 31) age = now - birthday age.days # 14368
10.9 數據壓縮
-
zlib
import zlib s = b'witch which has which witches wrist watch' len(s) t = zlib.compress(s) len(t) zlib.decompress(t) zlib.crc32(s)
10.10 性能測量
- timeit 快速測試小段代碼
>>> from timeit import Timer >>> Timer(’t=a; a=b; b=t’, ’a=1; b=2’).timeit() 0.57535828626024577 >>> Timer(’a,b = b,a’, ’a=1; b=2’).timeit() 0.54962537085770791
- Profile
import cProfile, pstats, io from pstats import SortKey import hashlib import time pr = cProfile.Profile() pr.enable() data = "你好" for i in range(10000): m = hashlib.md5(data.encode("gb2312")) time.sleep(2) pr.disable() s = io.StringIO() sortby = SortKey.CUMULATIVE ps = pstats.Stats(pr, stream=s).sort_stats(sortby) ps.print_stats() print(s.getvalue())
10.11 質量控制
-
doctests 能夠驗證文檔字符串中嵌入的測試
def average(values): """Computes the arithmetic mean of a list of numbers. >>> print(average([20, 30, 70])) 40.0 """ return sum(values) / len(values) import doctest doctest.testmod() # automatically validate the embedded tests
-
unittest
import unittest class TestStatisticalFunctions(unittest.TestCase): def test_average(self): self.assertEqual(average([20, 30, 70]), 40.0) self.assertEqual(round(average([1, 5, 7]), 1), 4.3) with self.assertRaises(ZeroDivisionError): average([]) with self.assertRaises(TypeError): average(20, 30, 70) unittest.main() # Calling from the command line invokes all tests
10.12 自帶電池
- xmlrpc.client xmlrpc.server
- json
- csv
- xml.etree.ElementTree xml.dom xml.sax
- sqlite3
- gettext locale codecs
11 標準庫簡介 – 第二部分
- 本部分介紹的是專業編程須要的更高級的模塊,不多用在小腳本中
11.1 格式化輸出
- reprlib 用於縮略顯示大型或深層嵌套的容器對象 >>> reprlib.repr(set(’supercalifragilisticexpialidocious’))
「{‘a’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, …}」
- pprint 美化輸出版 print
- textwrap 格式化文本段落,適應給定的屏幕寬度 print(textwrap.fill(doc, width=40))
11.2 模板
- from string import Template
>>> t = Template(’${village}folk send $$10 to $cause.’) >>> t.substitute(village=’Nottingham’, cause=’the ditch fund’) ’Nottinghamfolk send $10 to the ditch fund.’
11.3 使用二進制數據記錄格式
- struct 模塊的 pack() unpack()
11.4 多線程
- threading
11.5 日誌記錄
- logging
11.6 弱引用
- weakref 能夠沒必要建立引用就能跟蹤對象
11.7 用於操做列表的工具
- from array import array
- from collections import deque
- import bitset
- from heapq import heapify, heappop heappush
11.8 十進制浮點運算
- from decimal import * 能夠提供足夠的精度,也能知足浮點數的相等性
12 虛擬環境和包
12.1 概述
12.2 建立虛擬環境
- venv
12.3 使用 pip 管理包
- pip 經常使用命令 pip search xxx pip install novas pip install requests==2.6.0 pip install –upgrade requests pip show requests pip list pip freeze > requirements.txt pip install -r requirements.txt
13 接下來?
14 交互式編輯和編輯歷史
14.1 Tab 補全和編輯歷史
- python3 解釋器已經有 tab 補全了
- 默認配置,編輯歷史會被保存在 home 目錄 .pythonhistory
14.2 默認交互式解釋器的替代品
- ipython