1
Python 2
A quick introduction
Vincent CY Liao2014-04-20, revised at 2015-07-26
2
Outline
■ 簡介
■ 開發環境
■ 基本語言元素
3
簡介
■ 什麼是 Python ?
■ 2.7 vs. 3.x
4
什麼是 Python ?
■ 通用型的程式語言● 自動記憶體管理
● 支援物件語法
● 支援函數式程式設計
■ 發展現況
● Python 2 ( 最新版本 : 2.7.10; 2015-05-23)■ 於 2000-10-16 發表
■ 將會支援到 2020 年
● Python 3 ( 最新版本 : 3.4.3; 2015-02-25)■ 於 2008-12-03 發表
■ 語法不完全相容於 Python 2
http://www.python.org/
5
2.7 vs. 3.x
■ 大多在 Python 3 上有的新功能會移植回 2.7
■ 不會移植回 2.7 的功能
● 字串預設為 Unicode 字串
● 更清楚的分離處理 string 與 byte 的方式
■ 針對跨越 string 與 byte 的操作有嚴格的限制
● 例外串聯 (exception chaining)■ 在例外處理程式段落中再丟出例外■ 且仍可與原始例外有所聯結
● 僅使用 keyword 傳入的參數
● 更豐富的 tuple 展開語法
6
開發環境
■ 取得軟體
■ 建置與安裝
■ 編輯工具
■ 執行 Python
7
取得軟體
■ 大多數的 Linux 都內建有 Python
● Debian■ 6 (Squeeze): 2.6;■ 7 (Wheezy), 8 (Jessie): 2.7
● ubuntu■ 10.04 (Lucid): 2.6;■ 12.04 (Precise), 14.04(Trusty): 2.7
● RHEL■ 5 (Tikanga): 2.4;■ 6 (Santiago): 2.6
8
取得軟體 (cont.)
■ 檢視系統 Python 版本
● $ python -V
workstation:~ devuser$ python -VPython 2.7.10
9
取得軟體 (cont.)http://www.python.org/downloads/source/
10
建置與安裝
■ 準備安裝目錄
■ 安裝 Python
cd ~mkdir -p bin/pkg
mkdir tmpcd tmptar -zxf ~/Python-2.7.10.tgz
./configure –prefix=/home/USER/bin/pkg/python-2.7makemake install
cd ~/binln -s pkg/python-2.7/bin/python ../python --versionexport PATH=~/bin:$PATH
11
編輯工具
■ PyDev
● 基於 Eclipse 的整合開發界面
■ Geany● 支援程式碼折疊的文字編輯器
■ gedit
● GNOME 內建的圖形化文字編輯器
12
執行 Python
■ 互動模式
● 直接在終端機視窗執行 python指令
● 測試簡單的程式碼時使用
■ 檔案執行模式
● 平常用來執行 Python 程式的方法
● 將程式碼放在檔案中
● 執行 python [FILE_PATH]指令執行
● 如果希望程式執行完成後進入互動模式■ 使用 python -i [FILE_PATH]指令
13
執行 Python (cont.)
14
基本語言元素
■ 原始碼檔案諸元
■ 基本型別● 數值
● 字串
● 容器
■ 函數
■ 類別
■ 協定
■ 流程控制
■ 例外
■ 資源管理員
■ 程式模組
■ 常用的關鍵字
15
原始碼檔案
■ 以 .py作為慣用的延伸檔名
■ 縮排字元必須一致
● 不可混用 Tab 與空白
● Python 利用縮排進行程式區段的分隔
■ 建議使用 UTF-8 作為檔案的編碼
■ 除了作為進入點的執行檔外第一行建議空白
■ 第二行建議放置檔案編碼指示
■ 接下來應放置一字串說明程式碼用途
16
原始碼檔案 (cont.)
#!/usr/bin/python# -*- coding: utf-8 -*-
””” 範例的程式碼 ”””
import sys
# …
def _main(): # …
if __name__ == "__main__": _main()# <<< if __name__ == "__main__":
# vim: ts=4 sw=4 foldmethod=marker ai nowrap
17
基本數值型態
■ 整數
● int■ 32 bits 或 64 bits 等硬體支援的整數型別
■ 例 : 123
● long■ 64 bits 以上,規格上無限制
■ 例 : 1000000000000L
■ 浮點數
● float■ 64 bits■ 例 : 0.333
18
基本數值型態 (cont.)
■ 複數● 實數與虛數皆為浮點數
■ z.real■ z.imag
● 例 :■ 1.0 + 2.0j■ complex(1.0, 2.0)
19
基本字串型態
■ 單純字串
● str
● 例 :■ “start: - abc.\n- defghi.”■ r”a line is \n not a line.\n”
■ Unicode 字串
● unicode
● 例 :■ u”input 正體中文字串 is alright.”■ ur”a raw string \n 用 Unicode.”
20
基本容器型態
■ 串列 / 陣列
● tuple■ 內容與長度不可變動
■ 例 : (“element-0”, 1, 2.0,)
● list■ 內容與長度可變動
■ 例 : [“element-0”, 1, 2.0,]
■ 字典 / 雜湊表
● dict■ 內含的鍵值對沒有順序
■ 例 : {“key-0”: “value-0”, 1: “value-1”, “2”: 2.0,}
21
基本容器型態 (cont.)
■ 集合● 內容元素不重複並且沒有順序
● set■ 內容可被修改
■ 例 : set([1, 2.0, “3”,])
● frozenset■ 內容不可修改■ 記憶體使用較少■ 讀取速度較快
■ 例 : frozenset([1, 2.0, “3”,])
22
函數
■ 參數可以有預設值● 此類參數必須在參數定義的末端
■ 呼叫函數傳參數時可以使用鍵值對的方式
def my_function(arg0, arg1, arg2=”a-default”, arg3=None): ””” 函數說明 ””” # 函數實作
my_function(0, 1, ”2”, 3.0)my_function(0, 1) # 使用參數預設值my_function(0, arg1=1, arg3=3.0) # 使用鍵值對的方式指定參數
23
常用內建函數
■ int(), long(), float(), bool()● 強制轉型為數值,失敗時會丟出例外
■ str(v)
● 將指定的變數 v轉為字串
■ repr(v)
● 將指定的變數 v轉為程式碼表示字串
■ len(c)
● 取得指定的容器物件 c 內含的元素數量
24
類別
■ 屬性值可以動態的在類別方法中被加上● 不一定要在建構子中宣告
■ 但還是建議在建構子中建立類別物件屬性
■ 檢查物件是否為給定類別的類別物件
● isinstance(obj, class)
● isinstance(obj, (class1, class2,))
25
類別 (cont.)
class C(object): ””” 針對類別 C的說明 ”””
def __init__(self, v, *args, **kwds): super(C, self).__init__(*args, **kwds) self.p = 10 self.v = v
def m(self, arg1, arg2): ””” 針對方法 m的使用說明 ””” return self.p * self.v * arg1 * arg2
def __repr__(self): return “%s.C(%d)” % (__name__, self.v,)
26
協定
■ 用來實現相容型別的關係● 傳統物件導向語言使用繼承或是介面型別來達成
■ 為一組要支援該協定之物件應實作函數之規範● 有哪些函數應被實作
● 這些函數的參數與特定事件下的傳回值或例外
■ 以 iterator 協定為例
● iterator.__iter__()■ 傳回 iterator 自己
● iterator.next()■ 傳回下一個元素物件
■ 當沒有下一個元素物件時產生 StopIteration 例外
27
協定 (cont.)
■ 其他常見協定
● __str__■ 產生物件的文字表示字串
● __repr__■ 產生可以建立此類別物件的程式碼字串
● __call__■ 當物件被視為 callable 物件呼叫時執行
● __cmp__■ 比較兩個物件的數值大小
● __hash__■ 傳回物件的雜湊值,主要用在字典的鍵值或是集合中
28
流程控制
■ 條件執行
● if: … elif: … else: …
■ 迴圈
● for in: … else: …■ break■ continue■ 常搭配 xrange() 使用
● while: … else: …
if (v is True) and (w is True): # 當 v 與 w 為 True 時執行elif x is not True: # 當 x 不為 True 時執行else: # 當 v 與 w 不為 True 且 x 為 True
for e in c: # 對 c 中的所有元素 e 進行作業else: # 迴圈結束後執行
while a != b: # 對 a 與 b 的值仍相異時執行else: # 迴圈結束後執行
29
例外
■ 當異常時會有例外物件被丟出
● 例外物件為繼承自 Exception 的物件
■ 在程式中可攔截例外加以處理或忽略
● try: … except: … else: … finally: …
try: # 可能有例外的程式碼except ValueError as ve: pass # 忽略except: # 處理其餘異常else: # 正常完成finally: # 無論成功失敗最後都會執行
30
資源管理員
■ 取用資源後無論程式邏輯是否成功都必須釋放● 檔案
● 資料庫連線
■ 透過資源管理員 (Context Manager) 協定實現較為簡潔的語法
● 在 Context Manager 物件內需實做資源管理方法■ 進入資源使用程式區段時取得資源
▸ __enter__(self)
■ 離開資源取用程式區段時釋放資源▸ __exit__(self, exc_type, exc_value, exc_traceback)
● with … as ...
31
資源管理員 (cont.)
■ 大多數內建的資源物件都有支援
● open()
● threading.Lock(), thread.allocate_lock()
try: # 取得資源並使用 fp = open(“f.txt”, “r”) ...finally: # 釋放資源 fp.close()
with open(“f.txt”, “r”) as fp: # 使用資源 ...
with open(...) as fp, w_lock: # 使用資源 ...
32
程式模組
■ 將程式碼分門別類放置在不同檔案
■ 使用 import 關鍵字進行匯入
● import my_module as m
■ 也可放在資料夾中
● 資料夾中必須有 __init__.py檔案存在
● import my_package.my_module as m
■ 搜尋時是利用 sys.path串列內容依序找尋
33
常用關鍵字
■ A in B
● 元素 A 是否存在於容器 B 中
■ A is B
● 物件 A 與物件 B 是否為相同的參考
● 多用在判斷是否為 None, True, False
■ pass● 空指令
● 填充程式碼區段使之滿足語法需求
■ not, and, or● 邏輯運算
34
工具模組
■ 使用 pprint印出巢狀容器實體
■ 單元測試
■ YAML 資料表示與讀取
■ VirtualEnv 隔離環境
35
印出巢狀容器實體
■ 使用 pprint 模組可以印出較容易閱讀的格式
● Pretty Print
■ 自動地將巢狀容器實體縮排
>>> print c{'a': (1, 2, {3: '-', 5: '+', 7: '='}), 'c': {1: 1.0, 2: 2.0,3: 3.0}, 'b': 99.999999, None: [7, 8, 9]}
>>> import pprint>>> pprint.pprint(c){None: [7, 8, 9], 'a': (1, 2, {3: '-', 5: '+', 7: '='}), 'b': 99.999999, 'c': {1: 1.0, 2: 2.0, 3: 3.0}}
36
單元測試
■ 針對函數或是類別測試
● 將被測試程式 import 進測試程式
● 撰寫小的程式碼片段並驗證程式輸出
■ 透過單元測試可以讓程式碼的變動更有信心
■ Python 內建單元測試框架
● unittest
■ 當有很多程式要測試
● 將測試程式命名為 test*.py
● 執行 python -m unittest discover
37
單元測試 (cont.)import unittest
from … import target_module
class TestXXX(unittest.TestCase): def setUp(self): # 初始化測試用資源 def tearDown(self): # 釋放測試用資源 def test_xxxxxx(self): # 測試實作 t = target_module.target_function() self.assertEqual(t, ”correct value”)# ### class TestXXX
if __name__ == '__main__': unittest.main()
# vim: ts=4 sw=4 ai nowrap
38
YAML
■ 人類較易讀的資料表示格式
● YAML Ain't Markup Language
● 相較於 XML, JSON 等標記語言
■ 基本容器● 串列
■ 對應到 Python 的 list■ 內含元素可以是純量或是其他容器
● 字典■ 對應到 Python 的 dict■ 鍵的部分必須為純量
▸ 字串▸ 數值
39
YAML (cont.)import yaml
fp = open(”file.yaml”, ”r”)cmap = yaml.safe_load(fp)fp.close()
# 視YAML檔案的內容而定# cmap可能是 list或 dict
- item 1- item 2- item 3
key 1: value 1key 2: value 2key 3: value 3
- uid: 62031 name: ”Alica” workstop: ACUR01 eye-sight: 1.0 prefer-side: LEFT- uid: 79158 name: ”Bob” workstop: HEAVY max-force: 96.8
40
VirtualEnv
■ 建立隔離開的 Python 執行環境
● 內附有 PIP套件管理工具
■ 常見使用方式● 當與其他使用者共用主機時
● Python 應用程式使用相同但不同版本的函式庫
● 建立開發環境
41
VirtualEnv (cont.)
■ 下載
● https://pypi.python.org/pypi/virtualenv
■ 安裝到系統內mkdir tmpcd tmptar -zxf ~/virtualenv-13.1.0.tar.gzcd virtualenv-13.1.0/usr/bin/python setup.py build/usr/bin/python setup.py install
42
VirtualEnv (cont.)
■ 安裝到使用者自定目錄● 需編輯啟動指令稿mkdir tmpcd tmptar -zxf ~/virtualenv-13.1.0.tar.gzcd virtualenv-13.1.0/usr/bin/python setup.py buildmkdir -p /home/USER/bin/pkg/virtualenv/lib/python2.7/site-packagesexport PYTHONPATH=/home/USER/bin/pkg/virtualenv/lib/python2.7/site-packages/usr/bin/python setup.py install –prefix=/home/USER/bin/pkg/virtualenvvi /home/USER/bin/pkg/virtualenv/bin/virtualenv
#!/usr/bin/python# EASY-INSTALL-ENTRY-SCRIPT: 'virtualenv==13.1.0','console_scripts','virtualenv'__requires__ = 'virtualenv==13.1.0'import syssys.path.append("/home/USER/bin/pkg/virtualenv/lib/python2.7/site-packages")from pkg_resources import load_entry_point
43
VirtualEnv (cont.)
■ 日常使用方式
$ virtualenv ENV_NAME
$ source ENV_NAME/bin/activate(ENV_NAME)$
(ENV_NAME)$ pip install PyYAML
(ENV_NAME)$ python setup.py build(ENV_NAME)$ python setup.py install
(ENV_NAME)$ deactivate$
# 建立隔離環境
# 啟用隔離環境
# 使用PIP安裝套件 (以 PyYAML為例 )
# 也可以使用傳統的方式安裝套件
# 離開隔離環境
44
範例程式 :
http://goo.gl/DnVza3
45
Thank you !