10. มีอะไรให้ใช้บ้าง (Brief Tour of the Standard Library)

10.1 งานของระบบปฏิบัติการ (Operating System Interface)
10.2 ไฟล์ไวลด์คาร์ด (File Wildcards)
10.3 อาร์กิวเมนต์ (Command Line Arguments)
10.4 นำเข้า ส่งออก และเปลี่ยนทิศ (Error Output Redirection and Program Termination)
10.5 จับคู่สตริง (String Pattern Matching)
10.6 คณิตศาสตร์ (Mathematics)
10.7 อินเทอร์เน็ต (Internet Access)
10.8 วันที่และเวลา (Dates and Times)
10.9 การบีบอัดข้อมูล (Data Compression)
10.10 จับประสิทธิภาพ (Performance Measurement)
10.11 การควบคุมคุณภาพ (Quality Control)
10.12 พร้อมใช้ (Batteries Included)

เรามาดูว่าในไลบรารีมาตรฐานของไพธอน มีฟังก์ชันหรือเมธอดในมอดูล อะไรให้ใช้บ้าง


10.1 งานของระบบปฏิบัติการ (Operating System Interface)

os
มอดูล os มีเมธอดให้ใช้เยอะมาก
>>> import os
>>> os.system('time 0:02')
0

>>> os.getcwd()      # Return the current working directory
'C:\Python24'

>>> os.chdir('/server/accesslogs')

ต้องสั่งว่า import os เท่านั้น ห้ามใช้ว่า from os import * อันนี้เป็นภาคบังคับ ไม่งั้นชื่อฟังก์ชันจะตีกันเละกับบิลด์อินฟังก์ชัน
ถ้างงหรือหลงลืม ให้ใช้บิลด์อินฟังก์ชันสองตัวคือ dir() และ help() ดูว่าในมอดูลมีอะไรบ้าง

>>> import os
>>> dir(os)
<returns a list of all module functions>

>>> help(os)
<returns an extensive manual page created from the module's docstrings>
shutil
สำหรับงานจิปาถะเล็ก ๆ น้อย ๆ อาจใช้ตัวนี้แทน ดูจะอ่านเข้าใจง่ายกว่า
>>> import shutil
>>> shutil.copyfile('data.db', 'archive.db')
>>> shutil.move('/build/executables', 'installdir')


10.2 ไฟล์ไวลด์คาร์ด (File Wildcards)

glob
ใช้กับไวลด์คาร์ดคล่องตัวกว่า
 >>> import glob
>>> glob.glob('*.py')
['primes.py', 'random.py', 'quote.py']


10.3 อาร์กิวเมนต์ (Command Line Arguments)

sys
ใช้เยอะมาก เช่น สมมุติไฟล์ demo.py มีโค๊ดแบบนี้
#!/usr/bin/env python
import sys
print sys.argv

พอสั่งงานจากบรรทัดคำสั่งว่า "python demo.py one two three" จะได้ผลลัพธ์แบบนี้

$ python demo.py one two three
['demo.py', 'one', 'two', 'three']


10.4 นำเข้า ส่งออก และเปลี่ยนทิศ (Error Output Redirection and Program Termination)

sys
ใช้ sys เหมือนเดิม เพราะในนี้มีฟังก์ชันของ stdin stdout และ stderr เราจะผันการแสดงผลลัพธ์ไปทางไหน ก็ใช้จากมอดูลนี้
>>> sys.stderr.write('Warning, log file not found starting a new one
')
Warning, log file not found starting a new one

เวลาต้องการหยุดการทำงานของโปรแกรม ใช้ sys.exit() เป็นปกติ


10.5 จับคู่สตริง (String Pattern Matching)

re
ใช้งาน เรกูลาร์เอกเพรสชั่น (regular expression) ได้สะดวกและเป็นธรรมชาติ
>>> import re



>>> re.findall(rf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']

>>> re.sub(r'[a-z]+) ', r'', 'cat in the the hat')
'cat in the hat'
ใช้เมธอดของสตริงที่มีอยู่แล้ว
ถ้างานไม่ซับซ้อน ใช้อันนี้เร็วกว่า อ่านง่ายตรวจง่าย
>>> 'tea for too'.replace('too', 'two')
'tea for two' 


10.6 คณิตศาสตร์ (Mathematics)

math
มอดูลนี้ ใช้งานทศนิยมลอยและไลบรารีมาตรฐานทางคณิตศาตร์ได้คล่องตัวกว่า
>>> import math
>>> math.cos(math.pi / 4.0)
0.70710678118654757

>>> math.log(1024, 2)
10.0
random
งานการสุ่มแยกออกมาจาก math
>>> 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


10.7 อินเทอร์เน็ต (Internet Access)

urllib2
ใช้งานด้านลูกข่าย (client) เช่นเปิดดู url เป็นต้น
>>> 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
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 วันที่และเวลา (Dates and Times)

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 การบีบอัดข้อมูล (Data Compression)

มีเพียบ zlib  gzip  bz2  zipfile  tarfile
ลองดู zlib เป็นตัวอย่าง
>>> 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


10.10 จับประสิทธิภาพ (Performance Measurement)

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

สนุก ๆ นะครับ อันนี้เครื่องผม Intel Core2 Duo E6300 เริ่มเก่าแล้วละ ไพธอนรุ่น 2.4.4 [GCC 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)]

>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.21430277824401855

>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.14265108108520508

จะเห็นว่าใช้สลับแบบทูเปิลเร็วกว่าเยอะ โดยเฉพาะซีพียูรุ่นใหม่ ๆ (และไพธอนรุ่นเกือบใหม่)

อันนี้เป็นแบบเล่น ๆ ถ้าเอาจริงจังก็ยังมีมอดูล profile ใช้ดูเวลาโค๊ดเยอะ ๆ


10.11 การควบคุมคุณภาพ (Quality Control)

มาถึงนี่ได้ก็เริ่มเก๋าแล้วครับ อันนี้ใช้กับงานใหญ่ ๆ ที่เราจะจัดการดูแลโค๊ดเราให้มีมาตรฐานที่ดี เผื่อว่าใครจะเอาไปใช้ หรือจะทำงานร่วมกับใคร ก็จะเข้ากันได้แบบไร้ปัญหา

doctest
ใช้ตรวจสอบมอดูล โดยเราจะต้องเขียนผลการทดสอบที่เราหวังว่ามันจะเป็นแบบนั้นไว้ใน 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
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)
        self.assertRaises(ZeroDivisionError, average, [])
        self.assertRaises(TypeError, average, 20, 30, 70)

unittest.main() # Calling from the command line invokes all tests


10.12 พร้อมใช้ (Batteries Included)

ไพธอนพยายามทำให้ตัวเองพร้อมใช้งานมากที่สุด จึงพยายามจัดแพกเกจและมอดูลมาให้ครบถ้วน เช่น

  • มอดูล xmlrpclib และ SimpleXMLRPCServer ที่ทำงานกับ XML-RPC ได้ทั้งฝั่งลูกข่ายและแม่ข่าย โดยที่เราไม่ต้องเข้าไปจัดการกับโค๊ด XML เอง
  • แพกเกจ email ไม่เพียงแค่รับส่งอีเมล แต่มีฟังก์ชันของการเข้ารหัสและปรุงส่วนหัวของเมลให้ด้วย
  • แพกเกจ xml.dom และ xml.sax ใช้ในการทำงานกับภาษา XML อย่างมีประสิทธิภาพ ในทำนองเดียวกันมอดูล csv ก็รองรับการทำงานกับไฟล์ csv รวม ๆ กันแล้วก็ทำให้ลดความยุ่งยากในการส่งผ่านข้อมูลระหว่างงานได้เป็นอย่างดี
  • งานที่ต้องใช้งานหลายภาษาในหลายประเทศ ก็มีมอดูลหรือแพกเกจอย่าง gettext  locale และ codecs

บางทีการ "พร้อมใช้" ก็อาจสู้มอดูลจากข้างนอกไม่ได้เหมือนกัน แต่โดยรวม ๆ แล้วถือว่าเจ๋งพอตัว

Taxonomy upgrade extras: 
Creative Commons License ลิขสิทธิ์ของบทความเป็นของเจ้าของบทความแต่ละชิ้น
ผลงานนี้ ใช้สัญญาอนุญาตของครีเอทีฟคอมมอนส์แบบ แสดงที่มา-อนุญาตแบบเดียวกัน 3.0 ที่ยังไม่ได้ปรับแก้