1. Khái niệm và cách sử dụng module trong python
Như đã nói,Python cho phép chia chương trình thành
modules để có thể sử dụng lại trong các chương trình khác. Nó cũng có sẵn một tập hợp các modules chuẩn mà ta có thể sử dụng
lại trong chương trình của ta. Các thư viện
này cung cấp nhiều thứ, như file
I/O, các lời gọi hệ thống,
sockets,…Trong phần này chúng ta sẽ tìm
hiểu các kỹ thuật, đặc điểm của
các module.
Nếu
thoát khỏi trình thông dịch Python và vào lại nó, những định nghĩa (các
hàm và biến) đã viết sẽ bị mất. Vì thế,
nếu muốn viết chương trình tồn tại được lâu, tốt nhất là sử dụng một trình soạn
thảo để viết một file làm đầu vào cho trình biên dịch rồi chạy file đó. Cái này được gọi là một script (kịch bản). Hoặc khi muốn sử dụng một hàm đã xây dựng trong một vài chương
trình mà không muốn copy định nghĩa của nó vào từng chương trình. Để hỗ trợ điều này, Python có một cách đặt
các định nghĩa hàm trong một file và sử dụng chúng như một kịch bản hoặc trong
một instance tương tác của trình thông dịch. Một file như vậy gọi là một module. Các định nghĩa từ một module có thể được nhập
vào một module khác hoặc vào module chính (tập hợp các biến mà có thể truy nhập
đến một script được thi hành tại mức cao nhất và trong chế độ tính toán).
Một module là một file
chứa các định nghĩa và câu lệnh Python. Tên file là tên module với phần mở rộng
là .py. Trong một module, tên của module (như là một
xâu) là sẵn có như giá trị của biến toàn cục __name__. Ví dụ, dùng trình soạn thảo, soạn file fibo.py với nội dung như
sau:
. # Fibonacci numbers module
def
fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print
b,
a,
b = b, a+b
def fib2(n):
# return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a,
b = b, a+b
return result
Bây giờ mở trình thông dịch Pyhton và nhập module này bằng lệnh dưới
đây:
>>> import fibo
Thao tác
này không nhập tên của các hàm đã được định nghĩa trong fibo trực tiếp vào
trong bảng kí hiệu hiện thời; nó chỉ nhập tên của module fibo vào đó. Sử dụng tên module này để có thể truy nhập vào các hàm:
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Để thuận tiện, một hàm
trong module định sử dụng thường được đăng kí với một tên cục bộ:
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Một module có thể chứa các câu lệnh thực thi cũng như các
định nghĩa hàm. Các câu
lệnh đó được dùng để khởi tạo module đó. Chúng được thực hiện chỉ lần đầu tiên module
đó được nhập.
Mỗi một module có bảng kí hiệu riêng của nó, cái mà được sử dụng
như một bảng kí hiệu toàn cục cho tất cả các hàm được định nghĩa trong module
đó. Vì thế, các biến toàn cục
trong module có thể sử dụng mà không lo lắng về sự xung đột xảy ra với các biến
toàn cục của người sử dụng module đó.
Module cũng có thể được nhập vào một module khác. Nó như là một thông lệ nhưng không yêu cầu phải đặt tất cả các câu
lệnh import tại vị trí bắt đầu của một module (hoặc script). Tên module được
nhập vào đó được đặt trong bảng kí hiệu toàn cục của module nhập module đó.
Để
sử dụng modules trong Python, phải nhập nó bằng câu lệnh import. Ví dụ:
import math
Thao tác này sẽ nhập module chuẩn
math. Tất cả các hàm trong module này được gọi bằng
cách sử dụng qua tên module, ví dụ:
import math
print math.sqrt(10)
Có
một biến thể của câu lệnh import mà nhập các tên từ một module trực tiếp vào
bảng kí hiệu của module chứa module nhập đó. Ví dụ:
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Cũng có một biến thể để nhập tất cả các tên mà một module định nghĩa:
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Thao tác này nhập
tất cả các tên ngoại trừ những tên bắt đầu bằng dấu gạch dưới _
Đường dẫn tìm kiếm module
Khi một module tên là spam được nhập,
trình thông dịch sẽ tìm một file
tên là spam.py trong thư mục hiện
hành, và sau đó trong danh sách các thư mục
xác định bởi biến môi trường PYTHONPATH. Khi biến PYTHONPATH chưa được thiết lập
hoặc khi file đó không được tìm thấy, việc tìm kiếm được tiếp tục trong một đường
dẫn mặc định phụ thuộc khi cài đặt.
Thực
tế, các module được tìm kiếm trong danh sách các thư mục được đưa ra bởi biến
sys.path cái mà được khởi tạo từ thư mục chứa script vào ( hoặc thư mục hiện hành), PYTHONPATH và thư mục đường dẫn mặc định phụ
thuộc vào cài đặt. Điều này
cho phép chương trình Python biết cái mà chúng đang làm để sửa đổi hoặc thay
thế đường dẫn tìm kiếm module.
2. Các module chuẩn
Python
cung cấp một thư viện các module chuẩn. Một số module quan trọng được cài sẵn vào
trình thông dịch. Có một module cụ thể đáng
để chú ý là: sys, module này được cài sẵn vào mọi trình thông dịch Python. Các
biến sys.ps1 và sys.ps2 định nghĩa các xâu được sử dụng như dấu nhắc sơ cấp và
thứ cấp:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print 'Yuck!'
Yuck!
C>
Hai
biến trên chỉ được định nghĩa nếu trình thông dịch ở chế độ tương tác.
Biến
sys.path là một danh sách các xâu mà xác định đường dẫn tìm kiếm module của
trình thông dịch. Nó được khởi tạo một đường dẫn mặc định
từ biến môi trường PYTHONPATH, hoặc từ một giá trị mặc định được cài sẵn nếu
PYTHONPATH không được thiết lập. Có thể sửa đổi nó sử dụng thao tác danh
sách chuẩn:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
Sau
đây là danh sách đầy đủ các module chuẩn đã xây dựng trong Python. Một số
module có kèm theo tên các nền tảng mà module đó được
sử dụng:
3.
Thư viện các module chuẩn:
Phần này sẽ trình bày về một số
module chuẩn đã được xây dựng sẵn trong Python.
3.1.
Giao diện hệ điều hành
Module os cung
cấp rất nhiều hàm tương tác với hệ điều
hành:
>>> import os
>>> os.system('time 0:02')
0
>>> os.getcwd()
# Return the current working directory
'C:\\Python24'
>>> os.chdir('/server/accesslogs')
Hai hàm dir( ) và help( ) được dùng như những trợ giúp
khi làm việc vói các modules lớn như os:
>>> import os
>>> dir(os)
<returns a list of all module
functions>
>>> help(os)
<returns an extensive manual page created from
the module's docstrings>
Đối với nhiệm vụ quản lý thư mục và file hằng ngày, module shutil
cung cấp sự tương tác ở mức
độ cao hơn, sử dụng dễ dàng hơn:
>>> import shutil
>>> shutil.copyfile('data.db',
'archive.db')
>>> shutil.move('/build/executables',
'installdir')
3.2 Tệp với các kí tự đại diện
Module glob cung cấp một hàm để tạo danh sách từ việc tìm kiếm một thư mục dùng các kí tự đại diện. Ví dụ:
>>> import glob
>>> glob.glob('*.py')
['primes.py', 'random.py',
'quote.py']
3.3
Đối số dòng lệnh
Các script tiện ích
phổ biến
thường cần thiết lúc xử lý đối số dòng lệnh. Các đối số này được lưu trữ trong thuộc tính argv của module sys như một danh sách.Ví
dụ sau đưa ra kết quả khi chạy “python
demo.py one two three" tại dòng lệnh:
>>> import sys
>>> print sys.argv
['demo.py', 'one', 'two',
'three']
3.4.
Sự đổi hướng xuất lỗi và phần kết
thúc chương trình
Module sys cũng có các thuộc tính cho stdin, stdout và stderr . Đoạn mã sau để tạo ra các cảnh báo và thông điệp lỗi
làm cho chũng xuất hiện ngay cảkhi stdout được định hướng lại
>>> sys.stderr.write('Warning,
log file not found starting a new one\n')
Warning, log file not found
starting a new one
Hầu hết cách định hướng để kết thúc một script là xử dụng "sys.exit()".
3.5.
Kết hợp các kiểu xâu
module re cung cấp các công cụ biểu thức thông dụng cho việc xử lý xâu nâng cao .Đối với các thao tác
và biểu diễn phức tạp ,các biểu
thức chính qui đưa ra các giải pháp ngắn gọn và tối ưu. Ví dụ:
>>> import re
>>> re.findall(r'\bf[a-z]*',
'which foot or hand fell fastest')
['foot',
'fell', 'fastest']
>>> re.sub(r'(\b[a-z]+) \1',
r'\1', 'cat in the the hat')
'cat in the hat'
3.6.
Thư viện các hàm toán học
Danh sách các
module số và toán học bao gồm:
Các hàm toán học (sin() v.v...).
|
||
Các hàm toán học cho số phức.
|
||
Khai báo của các dạng số học
thập phân tổng quát
|
||
Sinh ra các số "giả"
ngẫu nhiên với các hàm phân bố xác
suất thông thường.
|
||
Các hàm sinh ra các “iterators” sử dụng trong các vòng lặp hiệu quả
|
||
Các hàm và thao tác có thứ tựưu
tiên cao hơn trên các đối tượng gọi được
|
||
Tất cả các toán tử chuẩn của Python được cài đặt sẵn
|
Module math cung
cấp các truy cập tới các hàm thư viện cơ bản của C đối với các phép toán trên số thực
>>> import math
>>> math.cos(math.pi / 4.0)
0.70710678118654757
>>> math.log(1024, 2)
10.0
Module random cung cấp một cách thức để tạo ra sự lựa chọn ngẫu nhiên
>>> import random
>>> random.choice(['apple',
'pear', 'banana'])
'apple'
>>> random.sample(xrange(100),
10) # sampling without replacement
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random()
# random float
0.17970987693706186
>>> random.randrange(6)
# random integer chosen from range(6)
4
Sau
đây, ta sẽ tìm hiểu về các hàm được xây dựng trong 2 module math và cmath.
a. Các hàm toán học trong module math:
Modul này luôn sẵn dùng. Nó cung cấp
phương thức truy nhập các hàm toán học được định nghĩa theo chuẩn C.
Module math cung cấp các hàm dưới đây. Tất cả đều trả về số thực ngoại trừ một số
trường hợp đặc biệt.
ceil(
|
x ) |
Hàm trả về giá trị cận trên của số thực x, tương ứng với giá trị nguyên nhỏ nhất lớn hơn x.
fabs(
|
x ) |
Giá trị tuyệt đối của
x
.
floor(
|
x ) |
Hàm trả về giá trị cận dưới của số thực x, tương ứng với giá trị nguyên lớn nhất nhỏ hơn x.
.
fmod(
|
x, y ) |
Trả về fmod(x,y), được định nghĩa theo chuẩn thư viện C. Chú ý rằng trong Python phép toán x % y có
thể không trả về cùng
một kết quả tương tự. Thực tế trong chuẩn thư viện C thì fmod(x,y) trả về chính
xác(phép toán, độ chính xác vô hạn)
bằng x-n*y với 1 vài số nguyên n
có cùng kết quả với dấu của x và
độ lớn trị tuyệt đối của y. Trong khi đó, đối với
Python thì phép toán x % y trả về kết quả là bao gồm cả dấu của y, và nó ko thểước tính chính
xác cho các đối số thực.Ví dụ,
fmod(-1e-100,1e100) là -1e-100, nhưng kết quả của
-1e-100 % 1e100 là -1e-100,điều này không thể đưa
ra kết quả chính xác đối với số thực, và làm tròn 1e100. Chính
vì nguyên nhân này, hàm fmod() thường được ưu
tiên khi làm việc với số thực, với
x % y trong Python thì được ưu
tiên với số nguyên.
frexp(
|
x ) |
Trả về phần
định trị và số mũ của x dưới dạng (m,e). m có giá trị thực còn e là số nguyên với x == m*2**e. Nếu x = 0, kết quả là (0.0,0), còn 0.5 <= abs(m) < 1.
ldexp(
|
x, i ) |
Trả về x * (2 ** i). Là hàm ngược
của hàm frexp().
modf(
|
x ) |
Trả về phần phân số và phần nguyên của x. Cả hai đều mang dấu của x và đều có
giá trị thực.
Chú ý rằng frexp() và
modf() có kiều gọi/ trả về khác nhau tương đương như trong C: Chúng lấy đối số đơn và trả về cặp
giá trị, đúng hơn là sựtrả về giá trị thứ 2
thông qua “tham số ra”( không có
những điều như vậy trong Python).
Đối với
các hàm ceil(),
floor() và modf(), chú ý là không phải tất cả các
số thực có giá trị lớn đều chính xác là số nguyên. Số thực
trong Python có độ chính xác
không vượt quá 32 bít( giống với
kiểu Double trong C), trong trường hợp giá trị thực x
có abs(x) >=2**52 thì tất nhiên sẽ không
có các bít phân số.
Các hàm mũ và logarit:
exp(
|
x ) |
Trả về e**x
log(
|
x [, base ]) |
Trả về logarit của x với cơ số đưa ra là base. Nếu không đưa cơ cố base,
thì tự động trả về logarit
tự nhiên của x( logarit với cơ số e).
log10(
|
x ) |
Trả về logarit cơ số 10 của x.
pow(
|
x, y ) |
Trả về x
** y
sqrt(
|
x ) |
Trả về căn bậc 2 của x.
Các hàm lượng giác:
acos(
|
x ) |
Trả về arc
coosin của x theo radian.
asin(
|
x ) |
Trả về arc
sin của x theo radian
atan(
|
x ) |
Trả về arc
tang của x theo radian
atan2(
|
y, x ) |
Trả về atan(y/x) theo radian. Kết quả nằm trong khoảng từ -pi đến pi. Vector trong mặt phẳng từ điểm gốc tọa độ tới điểm có tọa độ (x,y) tạo một
góc với trục tọa độ X . Điểm của atan2() mà dấu
của cả hai đầu vào được biết đến
nó, vì vậy nó có thể tính toán chính xác độ của góc. Ví dụ, atan(1) và
atan2(1,1) đều bằng pi/4 nhưng atan2(-1,-1) lại bằng –pi/4.
cos(
|
x ) |
Trả về giá
trị cosin của x
hypot(
|
x, y ) |
Trả về dạng
Oclit của sqrt(x*x+y*y).Đây là độ dài
véc tơ từ gốc tọa độ tới điểm có tọa độ (x,y).
sin(
|
x ) |
Trả về sin
của x theo radian
tan(
|
x ) |
Trả về tang
của x theo radian.
Hàm chuyển đổi góc:
degrees(
|
x ) |
Chuyển góc x từ radian
sang độ.
radians(
|
x ) |
Chuyển
góc x từ độ sang radian.
Các hàm hypebon:
cosh(
|
x ) |
Trả vè hyperbolic cosin của x.
sinh(
|
x ) |
Trả về hyperbolic sin của x.
tanh(
|
x ) |
Trả về hyperbolic tang của x.
Các hằng số toán học được
định nghĩa sẵn:
pi
Sốpi =
3.14159265358979….
e
Sốe.
b. Các hàm toán học cho số phức trong module cmath:
Module này cung cấp
cách truy nhập vào các hàm toán học cho số phức. Các hàm này gồm có:
acos(
|
x ) |
Trả về arccos
của x. Có 2 miền được chọn: 1 miền kéo dài về phía
phải từ 1 liên tục tới ∞. Miền còn lại kéo dài
về phía
trái từ -1
liên tục tới -∞.
acosh(
|
x ) |
Trả về hypedolic arccos của x. Chỉ có một miền được lấy ra, kéo dài
về phía trái từ 1 liên tục cho tới -∞.
asin(
|
x ) |
Trả về arcsin
của x.Có dải giá trị cũng giống
như arccos().
asinh(
|
x ) |
Trả về hyperbolic arcsin của x. Có 2 miền giá trị được lấy ra, kéo dài liên tục về bên trái từ ±1j tới ±-∞j. Những miền này cần tính toán đến các lỗi để chính xác hơn. Miền chính xác được lấy ra sẽ mở rộng theo trục ảo, một liên tục từ 1j tới ∞j từ phía phải và một liên tục từ -1j tới -∞j từ phía trái.
atan(
|
x ) |
Trả về arc
tang của x. Có 2 miền được lấy ra: Một kéo dài liên tục từ 1j theo trục sốảo
tới ∞j từ phía trái. Miền khác
kéo dài liên tục từ -1j dọc theo
trục sốảo tới ∞j từ phía trái.( Điều này sẽ chắc chắn thay đổi vì với miền cao hơn
sẽ liên tục từ nhiều phía khác).
atanh(
|
x ) |
Trả về hyperbolic
arc tang của x. Có 2 miền giá trị được
lấy ra: Một kéo dài liên tục từ 1
dọc theo trục số thực tới ∞. Miền còn lại kéo dài liên
tục từ-1 dọc theo trục số thực tới
-∞.( Điều
này chắc chắn sẽ bị thay đổi vì miền phải lấy ra trở nên liên tục từ phía khác)
cos(
|
x ) |
Trả về cosin của x.
cosh(
|
x ) |
Trả về hyperbolic cosin của x.
exp(
|
x ) |
Trả về giá trị mũ e**x.
log(
|
x [, base ]) |
Trả về logarit của x với cơ số là
base. Nếu base ko được đưa ra, trả về giá trị logarit tự nhiên của x. Có một miền được lấy ra,
từ 0 dọc theo miền âm trục số thực tới -∞. Được thay đổi trong phiên
bản 2.4 : đối số base được
thêm vào.
log10(
|
x ) |
Trả về logarit
cơ số 10 của x. Có miền tương tự như hàm log()
sin(
|
x ) |
Trả về sin của x.
sinh(
|
x ) |
Trả về hyperbolic sin của x.
sqrt(
|
x ) |
Trả về căn
bậc 2 của x. Miền được lấy ra tương tự như hàm log().
tan(
|
x ) |
Trả về tang của x.
tanh(
|
x ) |
Trả về hyperbolic tang của x.
Các hằng số đươc định
nghĩa trong module:
pi
Hằng số pi, tương tự như số thực
e
Hằng số e, tương tự như số thực
Chú ý rằng việc lựa
chọn các hàm trong module cmath cũng gần tương tự như trong module math nhưng
không hoàn toàn giống. Lý
do khiến người ta xây dựng lên cả 2
module phân biệt này là vì có người sử dụng
không thích dùng trong số phức,
và có lẽ không cần quan tâm chúng
là gì. Để xử lý với số phức họ có thể dùng hàm math.sqrt(-1),
và giá trị trả về của
các hàm trong cmath thì luôn là số phức,
mặc dù giá trị đó có thể rõ ràng là số thực ( trong trường hợp số phức có phần ảo là 0).
3.7.
Truy cập internet
Có một sốmodule để truy cập internet và
xử lý
các giao thức internet. Hai
module đơn giản nhất là urllib2 cho việc nhận dữ liệu từ url và smtplib cho gửi mail:
>>> import urllib2
>>> for line in
urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
... if 'EST' in
line or 'EDT' in line: # look for Eastern Time
... print line
<BR>Nov. 25, 09:43:32 PM EST
>>> 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()
3.8
Xử lý ngày và thời gian với module datetime
Module datetime cung cấp các lớp để thao với ngày và thời gian cho
cả yêu cầu đơn giản và phức tạp. Module này cũng hỗ trợ
các đối tượng nhận định yếu tố thời gian.
# 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
3.9.
Nén dữ liệu
Các định dạng nén và lưu trữ dữ liệu phổ biến
được hỗ trợ trực tiếp bởi rất nhiều thủ tục, bao gồm:zlib,gzip,bz2,zipfile và tarfile. Ví dụ:
>>> import zlib
>>> s = 'witch which has which witches wrist watch'
>>> len(s)
41
>>> t = zlib.compress(s)
>>> len(t)
37
>>> zlib.decompress(t)
'witch which has which witches wrist
watch'
>>> zlib.crc32(s)
226805979
3.10.
Đánh giá khả năng thực hiện
Một số ngưòi sử dụng Python quan tâm sâu sắc
trong việc tìm hiểu sự thực thi tương đối của các cách tiếp cận khác nhau tới
cùng một vấn đề
Chẳng hạn có thể thử chức năng packing và unpacking một tuple thay
vì phương pháp truyền thống là đối chỗ đối sô. Module timeit
cung cấp một ưu điểm thực hiện với mức độ vừa phải
>>> 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
3.11.
Kiểm tra chất lượng
Một phương pháp để
phát triển phần mềm chất lượng cao là viết chương trình kiểm tra cho mỗi hàm
lúc nó được phát triển và chạy kiểm tra thường xuyên trong suốt quá trình phát
triển
Module doctest cung cấp một công cụ cho việc kiểm tra một module và
kiểm tra hợp lệ được nhúng trong một docstring của chương trình.Việc tạo kiểm
tra cũng đơn giản như cắt và dán một lời gọi thông thường cùng với kết quả của
nó vào docstring đó.
Def average(values):
"""Computes
the arithmetic mean of a list of numbers.
>>> print average([20,
30, 70])
40.0
"""
return sum(values,
0.0) / len(values)
import doctest
doctest.testmod()
# automatically validate the embedded tests
Module unittest không cung cấp hiệu
qua như module doctest nhưng nó cho phép một tập hỗn hợp của các kiểm tra được
duy trì trong một file riêng biệt
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)
self.assertRaises(ZeroDivisionError,
average, [])
self.assertRaises(TypeError,
average, 20, 30, 70)
unittest.main() #
Calling from the command line invokes all tests
3.12
Định dạng đầu ra
Module repr cung
cấp một phiên bản mới của hàm rept( ) tuỳ biến đối với việc hiển thị ngắn gọn của các tập lớn hoặc được lồng nhau ở mức sâu.
>>> import repr
>>>repr.repr(set('supercalifragilisticexpialidocious'))
"set(['a', 'c',
'd', 'e', 'f', 'g', ...])"
Module pprint đưa ra điều khiển phức tạp hơn khi in
các đối tượng đã xây dựng sẵn và do người dùng định nghĩa theo một phương thức mà trình biên dịch có
thể hiểu được.
Khi kết quả dài hơn một dòng, ”pretty
printer “ xuống dòng và thụt vào đầu dòng để thể hiện
cấu trúc dữ liệu rõ ràng hơn
Ví dụ 2:
>>> import pprint
>>> t = [[[['black', 'cyan'], 'black',
['green', 'red']], [['magenta',
... 'yellow'],
'blue']]]
...
>>> pprint.pprint(t,
width=30)
[[[['black', 'cyan'],
'black',
['green',
'red']],
[['magenta',
'yellow'],
'blue']]]
Module textwrap định
dạng đoạn văn bản để lấp đầy chiều rộng màn hình đươc cho trước:
>>> import textwrap
>>> doc = """The
wrap() method is just like fill() except that it returns
... a list of strings
instead of one big string with newlines to separate
... the wrapped
lines."""
...
>>> print textwrap.fill(doc,
width=40)
The wrap() method is
just like fill()
except that it returns
a list of strings
instead of one big
string with newlines
to separate the
wrapped lines.
Module locale truy cập một cơ sở dữ
liệu của các định dạng dữ liệu xác định . Nhóm các thuộc tính của các hàm trong
module locale cung cấp một phương thức trực tiếp định dạng các số với việc tách
thành các nhóm
>>> import locale
>>> locale.setlocale(locale.LC_ALL,
'English_United States.1252')
'English_United States.1252'
>>> conv =
locale.localeconv() # get
a mapping of conventions
>>> x = 1234567.8
>>> locale.format("%d",
x, grouping=True)
'1,234,567'
>>> locale.format("%s%.*f",
(conv['currency_symbol'],
... conv['frac_digits'], x), grouping=True)
'$1,234,567.80'
3.13.
Kĩ thuật templating (tạm thời)
Module
string cung cấp một lớp Template linh hoạt với cấu trúc được đơn giản hoá phù hợp
cho việc soạn thảo. Điều này cho phép người sử dụng tuỳ
biến các ứng dụng của họ mà không cần phải thay đổi ứng dụng.
Định dạng này sử dụng
các placeholder( biến giữ chỗ) đuợc tạo thành bởi ký
hiệu $ sử dụng các định danh hợp lệ của Python (chỉ gồm các ký tự chữ, số và ký
tự gạch dưới). Bao quanh placeholder với dấu ngoặc {}cho
phép nó đi kèm với các ký tự chữ số mà không có dấu cách xen vào giữa. Ví dụ:
>>> 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.'
Phương thức substitute tạo
ra một lỗi KeyError khi một placeholder không được cung cấp trong một từ điển
hay một đối số từ khoá. Trong một ứng dụng dạng mail-mail, người sử dụng cung cấp
dữ liệu có thể không đầy đủ và phương thức safe_substitute có thể thích hợp
hơn—Nó sẽ để nguyên placeholder nếu dữ liệu bi lỗi
>>> t = Template('Return the
$item to $owner.')
>>> d = dict(item='unladen
swallow')
>>> t.substitute(d)
Traceback (most recent call last):
. . .
KeyError: 'owner'
>>> t.safe_substitute(d)
'Return the unladen swallow to $owner.'
Các Lớp con Template có
thể xác định một phân định tuỳ chọn. Chẳng hạn ,một tiện
ích đổi tên cho một trình duyệt ảnh có thể chọn để dùng kí hiệu % làm
placeholder như ngày hiện tại, số chuỗi ảnh hay kiểu định dạng file ảnh.
>>> import time, os.path
>>> photofiles =
['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
>>> class BatchRename(Template):
... delimiter =
'%'
>>> fmt = raw_input('Enter
rename style (%d-date %n-seqnum %f-format): ')
Enter rename style (%d-date %n-seqnum %f-format):
Ashley_%n%f
>>> t = BatchRename(fmt)
>>> date =
time.strftime('%d%b%y')
>>> for i, filename in
enumerate(photofiles):
... base, ext =
os.path.splitext(filename)
... newname =
t.substitute(d=date, n=i, f=ext)
... print '%s
--> %s' % (filename, newname)
img_1074.jpg --> Ashley_0.jpg
img_1076.jpg --> Ashley_1.jpg
img_1077.jpg --> Ashley_2.jpg
3.14.
Làm việc với các lớp bản ghi dữ liệu nhị phân
Module struct cung cấp
các hàm pack() và unpack() để làm việc với các định dạng
bản ghi nhị phân chiều dài thay đổi. Chương trình sau chỉ ra làm thế nào lặp
các thông tin header trong một file Zip ( với các
mã đóng gói “H” và “L” tương ứng số không dấu 2 và 4 bytes)
import struct
data =
open('myfile.zip', 'rb').read()
start = 0
for i in range(3):
# show the first 3 file headers
start
+= 14
fields
= struct.unpack('LLLHH', data[start:start+16])
crc32, comp_size,
uncomp_size, filenamesize, extra_size = fields
start
+= 16
filename
= data[start:start+filenamesize]
start
+= filenamesize
extra
= data[start:start+extra_size]
print
filename, hex(crc32), comp_size, uncomp_size
start
+= extra_size + comp_size # skip to the next header
3.15.
Kỹ thuật đa tuyến (Multi-threading)
Đa
tuyến (Threading) là một kĩ thuật cho các nhiệm vụ tách riêng mà không phụ thuộc
lấn nhau. Các tuyến có thể được sử dụng để nâng cao
tính đáp ứng của các ứng dụng mà chấp nhận người sử dụng nhập số liệu trong khi
các nhiệm vụ khác vẫn đang chạy.
Đoạn mã sau chỉ ra
cách mà module threading có thể thực hiện các nhiệm vụ trong khi chương trình
chính vẫn tiêp tục chạy
import
threading, zipfile
class
AsyncZip(threading.Thread):
def
__init__(self, infile, outfile):
threading.Thread.__init__(self)
self.infile
= infile
self.outfile = outfile
def
run(self):
f = zipfile.ZipFile(self.outfile, 'w',
zipfile.ZIP_DEFLATED)
f.write(self.infile)
f.close()
print 'Finished background zip of: ', self.infile
background =
AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print 'The main
program continues to run in foreground.'
background.join()
# Wait for the background task to finish
print 'Main program
waited until background was done.'
Vấn
đề khó khăn chủ yếu của các ứng dụng đa tuyến là các tuyến này cùng chia sẻ dữ
liệu và các tài nguyên khác.
Module threading
cũng cung cấp một sô công cụ đồng bộ hoá bao gồm locks, events, conditional
variables và semaphore.
Mặc
dù các công cụ này là rất mạnh, nhưng có những khó khăn trong khi thiết kế để
tránh các lỗi. Một phương pháp hữu hiệu là tập trung tất
cả sự truy cập tới một tài nguyên trong một thread đơn, sau đó sử dụng thủ tục
Queue để sử dụng thread này với các yêu cầu từ các thread khác. Ứng dụng
sử dụng đối tượng Queue cho việc liên lạc các thread bên trong chương trình và
sự kết hợp là dễ dàng hơn để thiết kế, dễ đọc hơn và đáng tin cậy hơn.
3.16.
Thao tác Logging
Module logging cung cấp
thao tác thoát khỏi hệ thống với đủ chức năng và
linh hoạt.
Đơn giản, một
thông điệp log được gửi tới file hoặc sys.stderr
import logging
logging.debug('Debugging
information')
logging.info('Informational
message')
logging.warning('Warning:config
file %s not found', 'server.conf')
logging.error('Error
occurred')
logging.critical('Critical
error -- shutting down')
Đoạn code này đưa ra dòng thông báo sau:
WARNING:root:Warning:config
file server.conf not found
ERROR:root:Error
occurred
CRITICAL:root:Critical
error -- shutting down
Theo mặc định, thông điệp thông tin và sữa lỗi có thể bị cấm và đầu
ra chỉ được gửi tới các lỗi chuẩn. Các lựa chọn đầu ra bao gồm các thông
điệp định tuyến thông qua email, datagram, socket hay HTTP server. Một bộ lọc
có thể chọn định tuyến khác nhau dựa trên quyền ưu tiên của thông điệp: DEBUG,
WARNING, ERROR VÀ CRITICAL
Thao tác
thoát khỏi hệ thống có thể được cấu hinh trực tiếp từ Python hoặc được nạp từ
file cấu hình có thể chỉnh sửa đối vói logging tuỳ ý mà không cần thay đổi ứng
dụng
3.17.
Các tham chiếu lỏng lẻo:
Pyhton tự động quản
lý bộ nhớ (đếm số lần tham chiếu của hầu hết các đối tượng và tập hợp không hợp
lệ để loại trừ chúng theo chu kì). Bộ
nhớ sẽ được giải phóng ngay sau khi tham chiếu cuối cùng tới nó được loại bỏ.
Phương pháp này
làm việc tốt đối với hầu hết ứng dụng nhưng đôi khi, các đối tượng cần được theo dõi trong suốt quá trình chúng được sử dụng, nhưng việc
theo dõi đó lại tạo ra một tham chiếu lâu dài. Module
weakref cung cấp các công cụ cho theo dõi đối tượng
mà không cần tạo một tham chiếu. Khi đối tượng không còn cần
nữa thì nó sẽ tự động bị xoá đi từ một bảng. Xét một ví dụ:
>>> import weakref, gc
>>> class A:
... def
__init__(self, value):
...
self.value = value
... def
__repr__(self):
... return str(self.value)
...
>>> a = A(10)
# create a reference
>>> d = weakref.WeakValueDictionary()
>>> d['primary']
= a
# does not create a reference
>>> d['primary']
# fetch the object if it is still alive
10
>>> del
a
# remove the one reference
>>> gc.collect()
# run garbage collection right away
0
>>> d['primary']
# entry was automatically removed
Traceback (most recent call last):
File
"<pyshell#108>", line 1, in -toplevel-
d['primary']
# entry was automatically removed
File
"C:/PY24/lib/weakref.py", line 46, in __getitem__
o = self.data[key]()
KeyError: 'primary'
3.18.
Các công cụ làm việc vói danh sách
Module array cung cấp đối tượng array() giống như một danh sách lưu trữ chỉ dữ liệu cùng loại
và lưu trữ nó liên tiếp nhau. Ví dụ sau đây chỉ ra một mảng các số được lưu trữ
như số nhị phân không dấu 2 byte (mã kiểu “H”) hơn là 16 bytes thông dụng cho một
mục đối với danh sách thông thường của đối tượng int của Python.
>>> from array import array
>>> a = array('H', [4000, 10,
700, 22222])
>>> sum(a)
26932
>>> a[1:3]
array('H', [10, 700])
Module collections cung
cấp đối tượng deque() cũng giống như danh sách nhưng tốc
độ thêm vào và lấy ra từ phía trái nhanh hơn nhưng tìm kiếm bên trong chậm hơn.
Đối tượng này phù hợp tốt cho sự thục hiện queue và tìm kiếm cây theo chiều rộng
>>> from collections import
deque
>>> d = deque(["task1",
"task2", "task3"])
>>> d.append("task4")
>>> print "Handling", d.popleft()
Handling task1
unsearched =
deque([starting_node])
def
breadth_first_search(unsearched):
node
= unsearched.popleft()
for
m in gen_moves(node):
if is_goal(m):
return m
unsearched.append(m)
Ngoài ra, để lựa chọn các thao
tác trên danh sách, thư viện cũng đưa ra các công cụ khác như module bisect với
các hàm cho các thao tác trên danh sách được lưu trữ
>>> import bisect
>>> scores = [(100, 'perl'),
(200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300,
'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500,
'python')]
Module heap cung cấp các hàm
cho việc thao tác các heap dựa trên danh sách thông thường. Phần tử có
giá trị thập nhất luôn ở vi trí 0 . Đây là một ứng dụng
hữu ích khi phải truy cập thường xuyên tới phần tử nhỏ nhất nhưng không muốn sắp
xếp toàn bộ danh sách
>>> from heapq import heapify, heappop, heappush
>>> data =
[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> heapify(data)
# rearrange the list into heap order
>>> heappush(data,
-5)# add a new entry
>>> [heappop(data)
for i in range(3)]
# fetch the three smallest entries
[-5, 0, 1]
3.19.
Số học trên dấu phẩy động hệ mười
Module
decimal đưa ra kiểu dữ liệu Decimal các phép toán số học với dấu phẩy động.
So với các thao tác trên kiểu float đã có sẵn của dấu phẩy động nhị phân, lớp mới
này đặc biệt có ích đối với các ứng dụng tài chính và những người sử dụng khác
cần việc biểu diển chính xác số thực, kiểm soát độ chính xác, điều chỉnh việc
làm tròn đúng qui tắc hay các yêu cầu điêu chỉnh, hay các ứng dụng mà người sử
dụng chấp nhận kết quả được tính toán bằng tay.
Chẳng
hạn tính 5% thuế trên 70 cent tiền điện thoại đưa lại kết quả khác nhau trong
kiểu số thực và số phẩy động nhị phân. Sự khác nhau này trở nên có ý
nghĩa nếu kết quả được làm tròn tới cent gấn nhất
>>> from decimal import
*
>>> Decimal('0.70') *
Decimal('1.05')
Decimal("0.7350")
>>> .70 * 1.05
0.73499999999999999
Việc biểu diễn
chính xác cho phép lớp Decimal thực hiện công việc tính toán và kiểm tra đẳng
thức điều mà không phù hợp đối với số dấu phẩy động nhị phân
>>> Decimal('1.00') %
Decimal('.10')
Decimal("0.00")
>>> 1.00 % 0.10
0.09999999999999995
>>> sum([Decimal('0.1')]*10) ==
Decimal('1.0')
True
>>> sum([0.1]*10) == 1.0
False
Module decimal cung cấp số và độ
chính xác theo yêu cầu
>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal("0.142857142857142857142857142857142857")
4.
Hàm dir( )
Hàm cài sẵn dir( ) được sử dụng để tìm ra các tên mà một module định
nghĩa. Nó trả về một danh sách đã sắp xếp các xâu. Ví
dụ:
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__',
'__stderr__',
'__stdin__', '__stdout__',
'_getframe', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'callstats',
'copyright',
'displayhook', 'exc_clear',
'exc_info', 'exc_type', 'excepthook',
'exec_prefix',
'executable', 'exit', 'getdefaultencoding', 'getdlopenflags',
'getrecursionlimit',
'getrefcount', 'hexversion', 'maxint', 'maxunicode',
'meta_path', 'modules',
'path', 'path_hooks', 'path_importer_cache',
'platform', 'prefix',
'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',
'setprofile',
'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',
'version',
'version_info', 'warnoptions']
Nếu không có các đối số, dir( ) liệt
kê các tên đã định nghĩa hiện thời:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__doc__', '__file__', '__name__', 'a', 'fib',
'fibo', 'sys']
Chú ý rằng nó liệt kê tất cả các loại tên: biến, module, hàm
v.v…
dir( ) không
liệt kê các tên của các hàm và biến được cài sẵn. Nếu muốn một danh sách của chúng,
chúng phải được định nghĩa trong một module chuẩn __builtin__:
>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', 'AttributeError',
'DeprecationWarning',
'EOFError', 'Ellipsis',
'EnvironmentError', 'Exception', 'False',
'FloatingPointError',
'FutureWarning', 'IOError', 'ImportError',
'IndentationError',
'IndexError', 'KeyError', 'KeyboardInterrupt',
'LookupError',
'MemoryError', 'NameError', 'None', 'NotImplemented',
'NotImplementedError',
'OSError', 'OverflowError',
'PendingDeprecationWarning', 'ReferenceError',
'RuntimeError',
'RuntimeWarning',
'StandardError', 'StopIteration', 'SyntaxError',
'SyntaxWarning',
'SystemError', 'SystemExit', 'TabError', 'True',
'TypeError',
'UnboundLocalError', 'UnicodeDecodeError',
'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError',
'UserWarning',
'ValueError', 'Warning', 'WindowsError',
'ZeroDivisionError', '_',
'__debug__', '__doc__', '__import__',
'__name__', 'abs', 'apply',
'basestring', 'bool', 'buffer',
'callable',
'chr', 'classmethod', 'cmp', 'coerce', 'compile',
'complex', 'copyright',
'credits', 'delattr', 'dict', 'dir', 'divmod',
'enumerate',
'eval', 'execfile', 'exit', 'file', 'filter', 'float',
'frozenset', 'getattr',
'globals', 'hasattr', 'hash', 'help', 'hex',
'id', 'input', 'int',
'intern', 'isinstance', 'issubclass', 'iter',
'len',
'license', 'list', 'locals', 'long', 'map', 'max', 'min',
'object',
'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range',
'raw_input', 'reduce',
'reload', 'repr', 'reversed', 'round', 'set',
'setattr',
'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super',
'tuple', 'type', 'unichr',
'unicode', 'vars', 'xrange', 'zip']
Hãy like nếu bài viết có ích →
Kết bạn với gisgpsrs trên Facebook
để nhận bài viết mới nóng hổi
Không có nhận xét nào:
Đăng nhận xét