Python 3 Tutorial 第三堂（1）函式、模組、類別與套件

Python supports procedural programming, to some extent, and OO. These two aren’t so different, and Python’s procedural style is still strongly influenced by objects (since the fundamental data types are all objects). Python supports a tiny bit of functional programming—but it doesn’t resemble any real functional language, and it never will.

• 抽象層的封裝與隔離
• 物件的狀態
• 名稱空間（Namespace）
• 資源的實體組織方式，像是原始碼檔案、套件（Package）等

函式

``````...
max1 = a if a > b else b
...
max2 = x if x > y else y
...
``````

``````def max(a, b):
return a if a > b else b
``````

``````maximum = max
maximum(10, 20) # 傳回 20
``````

``````lambda a, b: a if a < b else b
``````

``````min = lambda a, b: a if a < b else b
minimum = min
min(10, 20) # 傳回10
minimum(10, 20) # 傳回10
``````

模組

``````def max(a, b):
return a if a > b else b
def min(a, b):
return a if a < b else b

def sum(*numbers): # numbers 接受可變長度引數
total = 0
for number in numbers:
total += number

pi = 3.141592653589793
e = 2.718281828459045
``````

`import modu` 陳述句會在相同目錄下尋找 modu.py，如果沒找到，則會試著尋找在 `sys.path` 中遞迴地尋找 modu.py，如果還是沒有，則會引發 `ImportError` 例外。

``````import xmath
print('# import xmath')
print(xmath.pi)
print(xmath.max(10, 5))
print(xmath.sum(1, 2, 3, 4, 5))

print('# import xmath as math')
import xmath as math # 為 xmath 模組取別名為 math
print(math.e)

print('# from xmath import min')
from xmath import min  # 將 min 複製至目前模組，不建議 from modu import *，易造>成名稱衝突
print(min(10, 5))
``````

``````# import xmath
3.141592653589793
10
15
# import xmath as math
2.718281828459045
# from xmath import min
5
``````

類別

``````def account(name, number, balance):
return {'name': name, 'number': number, 'balance': balance}

def deposit(acct, amount):
if amount <= 0:
raise ValueError('amount must be positive')
acct['balance'] += amount

def withdraw(acct, amount):
if amount > acct['balance']:
raise RuntimeError('balance not enough')
acct['balance'] -= amount

def to_str(acct):
return 'Account:' + str(acct)
``````

``````import bank
acct = bank.account('Justin', '123-4567', 1000)
bank.deposit(acct, 500)
bank.withdraw(acct, 200)
print(bank.to_str(acct))
``````

``````class Account:
def __init__(self, name, number, balance):
self.name = name
self.number = number
self.balance = balance

def deposit(self, amount):
if amount <= 0:
raise ValueError('amount must be positive')
self.balance += amount

def withdraw(self, amount):
if amount > self.balance:
raise RuntimeError('balance not enough')
self.balance -= amount

def __str__(self):
return 'Account({0}, {1}, {2})'.format(
self.name, self.number, self.balance)
``````

`Account` 類別中，`__init__` 定義了物件的初始流程，取代了原本的 `account` 函式，注意到每個類別中的函式（或說是方法），首個參數「必定」接受物件本身，慣例上使用 `self` 名稱，相當於其他程式語言中 `this` 的概念，你可以說這是 Python 中「Explicit is better than implicit」的哲學，不過其實這還有讓類別動態調有時更為方便的實際意義，這是進階議題，這個課程中就不談了，有機會看看 Python 的專門書籍，應該都會談到…

``````import bank
acct = bank.Account('Justin', '123-4567', 1000)
acct.deposit(500)
acct.withdraw(200)
print(acct)
``````