บทท่ี 8 โมดลู และแพค็ เกจ (Modules and Packages) 1. โมดลู คืออะไร? โมดลู คอื การจดั กลุม่ ของแฟ้มตน้ ฉบบั ทถ่ี กู เขยี นดว้ ยภาษาไพธอนอยา่ งเป็นระบบตาม ภาระหน้าทท่ี ถ่ี กู กาหนดไว้ และสามารถเรยี กใชง้ านไดโ้ ดยสะดวก เช่น โมดลู ทบ่ี รหิ ารจดั การเกย่ี วกบั ระบบปฏบิ ตั กิ าร (Operating system: os) โมดลู ทใ่ี ชส้ าหรบั ประมวลผลทางคณติ ศาสตร์ (Mathematics: math) เป็นตน้ โดยกลุ่มของแฟ้มทถ่ี ูกเกบ็ รวมรวมไวอ้ าจจะประกอบไปดว้ ย ฟังชนั คลาส ตวั แปร หรอื runnable code กไ็ ด้ โมดลู มี 2 ประเภทคอื โมดลู ทม่ี าพรอ้ มกบั ตวั ภาษาไพธอน เชน่ โมดลู io, math, os, random, re, socket, string, sys, types, xml เป็นตน้ และโมดลู ทผ่ี เู้ ขยี นโปรแกรมเขยี นขน้ึ มาใช้ งานเอง โดยปกตชิ ่อื โมดลู จะมชี อ่ื เดยี วกบั ช่อื แฟ้มทจ่ี ดั เกบ็ โมดลู ไว้ แต่ถา้ แฟ้มนนั้ มหี ลายๆ โมดลู หรอื หลายฟังชนั ผเู้ ขยี นโปรแกรมควรตงั้ ชอ่ื แฟ้มใหส้ อดคลอ้ งกบั งานทท่ี า ตวั อยา่ งเช่น โมดลู CalAreaRectangle ทาหน้าทค่ี านวณหาพน้ื ทร่ี ปู สเ่ี หลย่ี มใดๆ ประกอบดว้ ยฟังชนั คานวณพน้ื ทส่ี เ่ี หลย่ี ม ดา้ นขนาน (Parallelogram) ผนื ผา้ (Rectangle) ดา้ นเท่า (Squre) คางหมู (Trapezoid) เปียกปนู (Rhomboid) รปู ว่าว (KiteRectangular) และสเ่ี หลย่ี มใดๆ (AnyRectangular) เมอ่ื สรา้ งฟังชนั แลว้ ใหท้ า การบนั ทกึ แฟ้มเป็นชอ่ื CalAreaRectagle.py ตวั อยา่ งโปรแกรมท่ี 8.1 โมดลู CalAreaRectangle Program Example 8.1: Module 1 # Calculating area of any rectangles 2 # This module named CalAreaRectangle.py 3 def rectangle(width, height): 4 return width * height 5 6 def squre(width1, width2): 7 return width1 * width2 8 9 def parallelogram(height, base): 10 return height * base 11 12 def trapezoid(sumofpararell, height): ห น้ า 181
13 return 0.5 * sumofpararell * height 14 15 def rhomboid(mulofdiagonal): 16 return 0.5 * mulofdiagonal 17 18 def RectangularKite(mulofdiagonal): 19 return 0.5 * mulofdiagonal 20 21 def AnyRectangular(diagonal, sumofbranch): 22 return 0.5 * diagonal * sumofbranch 2. การเรียกใช้งานโมดลู เมอ่ื ผเู้ ขยี นโปรแกรมตอ้ งการเรยี กใชฟ้ ังกช์ นั ทร่ี วบรวมเป็นโมดลู ไวแ้ ลว้ สามารถเรยี กโดยใช้ คาสงั่ import และนยิ มเขยี นคาสงั่ ดงั กลา่ วไวต้ งั้ แต่บรรทดั แรกของโปรแกรม สาหรบั วธิ กี ารเรยี กใช้ ฟังกช์ นั ในโมดลู สามารถกระทาได้ 4 วธิ ี ไดแ้ ก่ ใชค้ าสงั่ import, from module import function, import module import * และ import OldModule as NewModule ซง่ึ มรี ปู แบบการเรยี กใชด้ งั ต่อไปน้ี การใช้คาสงั่ import import module1[, module2[,... moduleN] โดย import คอื คาสงั่ เรยี กใชโ้ มดลู , module1 คอื ชอ่ื โมดลู ทต่ี อ้ งการเรยี กใชง้ าน และ module2…moduleN คอื ช่อื โมดลู อ่นื ๆ ทต่ี อ้ งการเรยี กใชเ้ พมิ่ เตมิ (กรณใี ชง้ านมากกว่า 1 โมดลู ) หลกั การใช้งาน: เหมาะสาหรบั ผทู้ ต่ี อ้ งการเรยี กใชง้ านฟังชนั และตวั แปรทงั้ หมดในโมดลู เขา้ มาทางานในโปรแกรม ตวั อย่าง เช่น import sys, io, math การใช้คาสงั่ from module import function from moduleName import funcName1[, FuncName2[, ... FuncNameN]] โดย from moduleName import คอื คาสงั่ เรยี กใชโ้ มดลู ช่อื moduleName, funcName1,...,N คอื ชอ่ื ของฟังชนั ทอ่ี ยใู่ นโมดลู moduleName หลกั การใช้งาน: เหมาะสาหรบั ผทู้ ต่ี อ้ งการเรยี กฟังชนั หรอื ตวั แปรเฉพาะทต่ี อ้ งการมาใช้ งานเท่านนั้ ตวั อย่าง from math import pi, pow การใช้คาสงั่ from module import * from moduleName import * ห น้ า 182
โดย from moduleName import คอื คาสงั่ เรยี กใชโ้ มดลู ชอ่ื moduleName, * คอื ฟังชนั ทงั้ หมดทอ่ี ยใู่ นโมดลู moduleName หลกั การใช้งาน: เหมาะสาหรบั ผทู้ ต่ี อ้ งการเรยี กฟังชนั หรอื ตวั แปรทงั้ หมดในโมดลู มา ทางาน ตวั อย่าง from math import * การใช้คาสงั่ import OldModule as NewModule import OldModule as NewModule โดย import OldModule คอื คาสงั่ เรยี กใชโ้ มดลู ช่อื OldModule และ as NewModule คอื โมดลู ใหมท่ ถ่ี กู เปลย่ี นชอ่ื จาก OldModule ไปเป็น NewModule หลกั การใช้งาน: เหมาะสาหรบั ผทู้ ต่ี อ้ งการเปลย่ี นชอ่ื โมดลู เดมิ ใหเ้ ป็นช่อื ใหม่ ตวั อย่าง import math as MAT print(MAT.pi) เปลย่ี นชอ่ื โมดลู จาก math เป็นชอ่ื MAT หรอื ใชค้ าสงั่ from module import OldName as NewName เช่น from math import sqrt as SquareRoot เปลย่ี นช่อื ฟังชนั จาก sqrt เป็น SquareRoot print(SquareRoot(5)) Caution! เมอ่ื ไพธอนแปลคาสงั่ มาถงึ คาสงั่ import แลว้ ไพธอนจะทาการโหลดโมดลู ทร่ี ะบุไว้ ขน้ึ มาทางาน โดยคน้ หาทอ่ี ยขู่ องโมดลู จาก path ซง่ึ ถกู กาหนดไวใ้ นระบบปฏบิ ตั กิ าร ถา้ ไพ ธอนคน้ หาแฟ้มดงั กล่าวไมพ่ บ จะทาใหโ้ ปรแกรมเกดิ ขอ้ ผดิ พลาด (สาหรบั วนิ โดวสก์ าหนด path ท่ี system Advanced system settings Environment variables System variables Path) โปรแกรมท่ี 8.2 แสดงตวั อยา่ งการเรยี กใชโ้ มดลู CalAreaRectangle โดยใชค้ าสงั่ import (ผเู้ ขยี น โปรแกรมควรเกบ็ แฟ้ม CalAreaRectangle.py ไวใ้ นไดเรคทรอรเี ดยี วกบั โปรแกรมทเ่ี รยี กใชง้ าน) ตวั อยา่ งโปรแกรมท่ี 8.2 การเรยี กใชโ้ มดลู ดว้ ยคาสงั่ import Program Example 8.2: calling CalAreaRectangle module 1 # import CalAreaRectangle module 2 import CalAreaRectangle 3 print(\"Area of Rectangle :\",CalAreaRectangle.rectangle(3, 4)) 4 print(\"Area of Squre :\",CalAreaRectangle.squre(3, 3)) 5 print(\"Area of Parallelogram :\",CalAreaRectangle.parallelogram(1.5, 4.5)) 6 print(\"Area of Trapezoid :\",CalAreaRectangle.trapezoid(5, 2.5)) 7 print(\"Area of Rhomboid :\",CalAreaRectangle.rhomboid(8)) ห น้ า 183
8 print(\"Area of RectangularKite :\",CalAreaRectangle. RectangularKite(12)) 9 print(\"Area of AnyRectangular :\",CalAreaRectangle.AnyRectangular(3.5, 6) Area of Rectangle : 12 Area of Squre : 9 OUTPUT Area of Parallelogram : 6.75 Area of Trapezoid : 6.25 Area of Rhomboid : 4.0 Area of KiteRectangular : 6.0 Area of AnyRectangular : 10.5 จากตวั อยา่ งโปรแกรมท่ี 8.2 บรรทดั ท่ี 2 แสดงตวั อยา่ งการใชค้ าสงั่ import โมดลู CalAreaRectangle เขา้ มาทางาน เมอ่ื ตอ้ งการเรยี กใชฟ้ ังชนั ใดๆ ในโมดลู ดงั กลา่ ว ผใู้ ชจ้ าเป็นตอ้ งอา้ ง ชอ่ื โมดลู แลว้ ตามดว้ ยช่อื ฟังชนั ทต่ี อ้ งการใชง้ าน (โดยใช้ . ในการอา้ งองิ ถงึ ฟังชนั ) เช่น ในบรรทดั ท่ี 3 ตอ้ งการเรยี กใชฟ้ ังชนั CalAreaRectangle.rectangle พรอ้ มกบั ส่งค่าคงทเ่ี ป็นอารก์ วิ เมนตใ์ หก้ บั ฟังชนั 2 ตวั คอื 3 และ 4 สาหรบั การเรยี กใชฟ้ ังชนั อ่นื ๆ กท็ าในลกั ษณะเดยี วกนั สาหรบั ตวั อยา่ งท่ี 8.3 แสดงการ ใชค้ าสงั่ from module import function ตวั อยา่ งโปรแกรมท่ี 8.3 การเรยี กใชโ้ มดลู ดว้ ยคาสงั่ from module import function Program Example 8.2: calling CalAreaRectangle module 1 # from moduleName import funcName example 2 from CalAreaRectangle import rectangle, squre, parallelogram, trapezoid, rhomboid, RectangularKite, AnyRectangular 3 print(\"Area of Rectangle :\",rectangle(3, 4)) 4 print(\"Area of Squre :\",squre(3, 3)) 5 print(\"Area of Parallelogram :\",parallelogram(1.5, 4.5)) 6 print(\"Area of Trapezoid :\",trapezoid(5, 2.5)) 7 print(\"Area of Rhomboid :\",rhomboid(8)) 8 print(\"Area of KiteRectangular :\", RectangularKite(12)) 9 print(\"Area of AnyRectangular :\",AnyRectangular(3.5, 6)) Area of Rectangle : 12 Area of Squre : 9 OUTPUT Area of Parallelogram : 6.75 Area of Trapezoid : 6.25 Area of Rhomboid : 4.0 Area of KiteRectangular : 6.0 Area of AnyRectangular : 10.5 จากตวั อยา่ งโปรแกรมท่ี 8.3 บรรทดั ท่ี 2 แสดงการใชค้ าสงั่ from module import function โปรแกรมเรมิ่ ตน้ โดยการ import โมดลู CalAreaRectangle เขา้ มาก่อนโดยใชค้ าสงั่ from CalAreaRectangle จากนนั้ ทาการเลอื กเอาเฉพาะฟังชนั ทต่ี อ้ งการใชง้ านจรงิ ๆ มาทางานเท่านนั้ โดยใช้ คาสงั่ import rectangle, squre, parallelogram, trapezoid, rhomboid, RectangularKite, ห น้ า 184
AnyRectangular เมอ่ื โปรแกรมตอ้ งการเรยี กใชฟ้ ังชนั ไมจ่ าเป็นตอ้ งอา้ งชอ่ื โมดลู เหมอื นการใชค้ าสงั่ import แบบปกติ เช่น print(\"Area of Rectangle :\", rectangle(3, 4)) ในบรรทดั ท่ี 3 เป็นตน้ Tips: เมอ่ื ตอ้ งการเรยี กใชฟ้ ังชนั ในโมดลู โดยไมต่ อ้ งการอา้ งช่อื ของโมดลู ใหใ้ ชค้ าสงั่ form ModuleName import function และสามารถเลอื กเอาเฉพาะฟังชนั ทต่ี อ้ งการใชจ้ รงิ ๆ เทา่ นนั้ เมอ่ื ผเู้ ขยี นโปรแกรมตอ้ งการดรู ายละเอยี ดของฟังชนั ตวั แปร ภายในโมดลู ทโ่ี หลดเขา้ มาใชง้ านใน โปรแกรมสามารถใชค้ าสงั่ dir(ModuleName) ดงั ตวั อยา่ งต่อไปน้ี >>> import CalAreaRectangle >>> dir(CalAreaRectangle) ['AnyRectangular', 'KiteRectangular', '__builtins__', '__cached__', '__doc__', '__file__', '__initializing__', '__loader__', '__name__', '__package__', 'parallelogram', 'rectangle', 'rhomboid', 'squre', 'trapezoid'] โดยตวั แปร __name__ เกบ็ ชอ่ื ของโมดลู (แสดงช่อื โดยใชค้ าสงั่ print(CalAreaRectangle.__file__)) และตวั แปร __file__ เกบ็ ช่อื ของแฟ้มทโ่ี หลดมาใชง้ าน (แสดงชอ่ื โดยใชค้ าสงั่ print(CalAreaRectangle.__file__)) มนี ามสกุลเป็น .py Tips: เมอ่ื ผเู้ ขยี นโปรแกรม import โมดลู ใดโมดลู หน่งึ เขา้ มาในโปรแกรมแลว้ สามารถ เรยี กดฟู ังชนั ในโมดลู เหลา่ นนั้ ดว้ ยคาสงั่ dir(ModuleName) เชน่ dir(CalAreaRectangle) คาสงั่ dir() สามารถเรยี กดรู ายละเอยี ดของโมดลู ทต่ี ดิ ตงั้ มากบั ไพธอนไดเ้ ชน่ เดยี วกนั >>> import math >>> dir(math) ['__doc__', '__loader__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'] ความแตกต่างระหว่าง import, from module import function และ import * สาหรบั ความแตกต่างระหวา่ งคาสงั่ import และ from module import function คอื import จะ โหลดโมดลู พรอ้ มกบั ฟังชนั ทงั้ หมดเขา้ มาในโปรแกรมทเ่ี รยี กใชง้ าน แต่ form module import function จะสามารถเลอื กเอาเฉพาะฟังชนั ทจ่ี าเป็นตอ้ งใชง้ านเขา้ มาเท่านนั้ ส่งผลใหป้ ระหยดั พน้ื ทห่ี น่วยความจา ในการทางานลงได้ แต่ผเู้ ขยี นโปรแกรมตอ้ งจดจาใหไ้ ดว้ ่าแต่ละโมดลู มฟี ังชนั ใหเ้ รยี กใชง้ านอะไรบา้ ง ห น้ า 185
สาหรบั คาสงั่ from module import * จะใชเ้ มอ่ื ผเู้ ขยี นโปรแกรมต้องการนาเขา้ ฟังชนั ทงั้ หมดใน โมดลู เขา้ มาทางานในโปรแกรม ซง่ึ ไมแ่ ตกต่างกบั คาสงั่ import moduleName เพราะฉนนั้ ไพธอน แนะนาใหใ้ ชค้ าสงั่ น้เี ท่าทจ่ี าเป็นเท่านนั้ สาหรบั การใชง้ าน import OldModule as NewModule และ from module import OldName as NewName เป็นการเปลย่ี นชอ่ื โมดลู และฟังชนั จากช่อื เดมิ เป็นช่อื ใหมเ่ ท่านนั้ ตาแหน่งท่ีอย่ขู องการโหลดโมดลู มาใช้งาน เมอ่ื ผเู้ ขยี นโปรแกรมโหลดโมดลู ใดโมดลู หน่งึ เขา้ มาทางานในโปรแกรม ตวั แปลภาษาไพธอนจะ เรม่ิ ทาการคน้ หาโมดลู ตามลาดบั ดงั น้ี 1. คน้ หาแฟ้มทเ่ี กบ็ โมดลู ในไดเรคทรอรปี ัจจบุ นั เมอ่ื ไมพ่ บโมดลู ทต่ี อ้ งการจะคน้ หาต่อในลาดบั ท่ี 2 2. ไพธอนจะคน้ หาแฟ้มในแต่ละไดเรคทรอรที ถ่ี ูกระบุใน PYTHONPATH ถา้ ไมพ่ บโมดลู ท่ี ตอ้ งการจะคน้ หาต่อไปในลาดบั ท่ี 3 3. ไพธอนจะคน้ หาใน default path ซง่ึ ถูกกาหนดโดยระบบปฏบิ ตั กิ ารทต่ี ดิ ตงั้ ไพธอนไว้ เช่น ถา้ ตดิ ตงั้ ไวบ้ นวนิ โดวส์ default path จะถกู กาหนดไวท้ ่ี C:\\PythonXX (โดย XX คอื เวอรช์ นั ของไฟธอน เชน่ Python34) แต่ถา้ เป็น UNIX โดยปกตจิ ะอยทู่ ่ี /usr/local และ /lib/python ถา้ ไพธอนยงั หาโมดลู ไมเ่ จอใน path ทร่ี ะบไุ วท้ งั้ หมด จะเกดิ error ขน้ึ และไมส่ ามารถใช้ งานโมดลู นนั้ ๆ ได้ เมอ่ื ผเู้ ขยี นโปรแกรมตอ้ งการดู default path ทไ่ี พธอนไดก้ าหนดไว้ สามารถใชค้ าสงั่ ดงั น้ี >>> import sys >>> print(sys.path) ['C:\\\\Python34\\\\Lib\\\\idlelib', 'C:\\\\Windows\\\\SYSTEM32\\\\python34.zip', 'C:\\\\Python34\\\\DLLs', 'C:\\\\Python34\\\\lib', 'C:\\\\Python34', 'C:\\\\Python34\\\\lib\\\\site- packages'] ผเู้ ขยี นโปรแกรมสามารถเพม่ิ เตมิ ทอ่ี ยขู่ องโปรแกรมหรอื โมดลู ทเ่ี ขยี นขน้ึ ไดเ้ อง โดยใชค้ าสงั่ sys.path.append(PATH_NAME) เช่น >>> import sys >>> sys.path.append('C:\\\\test') >>> print(sys.path) ['C:\\\\Python33\\\\Lib\\\\idlelib', 'C:\\\\Windows\\\\SYSTEM32\\\\python33.zip', 'C:\\\\Python33\\\\DLLs', 'C:\\\\Python33\\\\lib', 'C:\\\\Python33', 'C:\\\\Python33\\\\lib\\\\site- packages', 'C:\\\\test'] ห น้ า 186
PYTHONPATH ตวั แปร PYTHONPATH เป็นตวั แปรระบบ ทถ่ี ูกสรา้ งขน้ึ จากระบบปฏบิ ตั กิ าร ซง่ึ ตวั แปร ดงั กลา่ วจะเกบ็ บญั ชรี ายชอ่ื ทอ่ี ยขู่ องไดเรคทรอรที ร่ี ะบบใชส้ าหรบั ทางาน รวมถงึ ไดเรคทรอรขี องไพธอน ดว้ ย ตวั แปรดงั กลา่ วสามารถกาหนดใหมไ่ ด้ โดยใชร้ ปู แบบคาสงั่ คอื บนระบบปฏบิ ตั กิ ารวนิ โดวส์ เลอื ก start run cmd set PYTHONPATH=c:\\python34\\lib; บนระบบปฏบิ ตั กิ ารยนู กิ ส์ เปิด terminal set PYTHONPATH=/usr/local/lib/python บนระบบปฏบิ ตั กิ ารวนิ โดวส์ สามารถกาหนดผ่านกราฟฟิกได้ โดยเลอื ก My Computer คลกิ ขวาเลอื ก properties เลอื ก System Advanced system settings Environment variables.. System variables Path edit ใหก้ าหนด path ดงั น้คี อื C:\\YourPath เช่น %C:\\Python34 กดป่มุ OK ไปเรอ่ื ยๆ จนกว่าหน้าต่างการทางานจะหมด การโหลดโมดลู มาใช้งานใหม่ โดยปกตเิ มอ่ื ผเู้ ขยี นโปรแกรมทาการนาเขา้ โมดลู ใดๆ เขา้ มาทางานในโปรแกรม นิยมประกาศไว้ บรรทดั บนสุดของโปรแกรม โดยโมดลู นนั้ ๆ จะถกู โหลดมาใชง้ านเพยี งครงั้ เดยี วเท่านนั้ (ไพธอนแนะนา ใหโ้ หลดโมดลู เพยี งแค่ครงั้ เดยี วจนกว่าโปรแกรมจะหยุดการทางาน) จนโปรแกรมยตุ กิ ารทางาน แต่ถา้ ผเู้ ขยี นโปรแกรมตอ้ งการโหลดโมดลู ใดโมดลู หน่งึ ใหท้ างานอกี ครงั้ ในโปรแกรม มรี ปู แบบคาสงั่ ดงั น้ี reload(module_name) ตวั อยา่ งเช่น reload(CalAreaRectangle) 3. แพค็ เกจ (Packages) โปรแกรมทม่ี ขี นาดใหญ่ จะประกอบดว้ ยคลาส โมดลู และฟังชนั อยเู่ ป็นจานวนมาก เราสามารถ จดั หมวดหมู่ ของคลาส โมดลู และฟังชนั ใหเ้ ป็นระเบยี บและงา่ ยต่อการใชง้ าน โดยการนาเอาคลาส และ โมดลู เหล่านนั้ รวมเขา้ กนั ไวต้ ามลาดบั ชนั้ ดว้ ยโครงสรา้ งแฟ้มอยา่ งเป็นระบบ และใช้คาสงั่ import ใน การเรยี กใช้ สาหรบั การสรา้ งแพค็ เกจมขี นั้ ตอนดงั น้ี ห น้ า 187
จากทก่ี ล่าวมาแลว้ ขา้ งตน้ ผเู้ ขยี นไดส้ รา้ งโมดลู และเกบ็ ไวใ้ นแฟ้มชอ่ื ว่า CalAreaRectangle.py ไวแ้ ลว้ ต่อไปผเู้ ขยี นจะสรา้ งโมดลู เพม่ิ ขน้ึ อกี 1 โมดลู คอื โมดลู คานวณหาพน้ื ทส่ี ามเหลย่ี ม (CalAreaTriangle) แสดงในโปรแกรมท่ี 8.4 ซง่ึ ประกอบไปดว้ ย สามเหลย่ี มทวั่ ไป (Triangle) สามเหลย่ี มดา้ นเท่า (Equilateral) สามเหลย่ี มหน้าจวั่ (Isosceles) และสามเหลย่ี มมมุ ฉาก (Pythagorean) แลว้ ทาการบนั ทกึ เป็นแฟ้มชอ่ื CalAreaTiangle.py และเกบ็ โมดลู ทงั้ สอง (CalAreaRectangle และ CalAreaTiangle) ไวใ้ นไดเรคทรอรชี ่อื CalArea ดงั รปู ดา้ นล่าง ตวั อยา่ งโปรแกรมท่ี 8.4 โมดลู CalAreaTriangle Program Example 8.4: CalAreaTriangle module 1 # Calculating Triangles Area 2 # This module named CalAreaTriangle.py 3 def triangle(height, base): 4 return 1/2 * height * base 5 6 def equilateral(width): 7 return 3**(1/2) * width * width 8 9 def isosceles(base, sidebase): 10 return base/4 * 4 * (((sidebase*sidebase) - (base*base)))**(1/2) 11 12 def pythagorean(perpendicular): 13 return 0.5 * perpendicular * perpendicular ขนั้ ตอนต่อไป ใหผ้ เู้ ขยี นโปรแกรมสรา้ งแฟ้มช่อื __init__.py เพอ่ื ใชส้ าหรบั เกบ็ คา่ คอนฟิกเรม่ิ ตน้ สาหรบั เรยี กใชง้ านแพค็ เกจ CalArea และเกบ็ ไวใ้ นไดเรคทรอรชี ่อื CalArea รว่ มกนั กบั แฟ้ม CalAreaRectangle.py และ CalAreaTriangle.py จากนนั้ ทาการกาหนดคา่ ใหก้ บั แฟ้ม __init__.py ดงั น้ี #This initial file for CalArea Package (__init__.py) from .CalAreaRectangle import rectangle, squre, parallelogram, trapezoid, rhomboid, KiteRectangular, AnyRectangular from .CalAreaTriangle import triangle, equilateral, isosceles, pythagorean ในแฟ้ม __init__.py ใหผ้ เู้ ขยี นโปรแกรมทาการ import โมดลู พรอ้ มกบั ฟังชนั ทงั้ หมดทต่ี อ้ งการใชง้ าน ดงั ตวั อยา่ งทแ่ี สดงไวข้ า้ งบน จากนนั้ ทดสอบเขยี นโปรแกรมเพ่อื เรยี กใชง้ านแพค็ เกจ CalArea โดยใช้ คาสงั่ import แลว้ ตามดว้ ยช่อื ของแพค็ เกจ (สาหรบั ในตวั อยา่ งคอื import CalArea) ดงั ตวั อยา่ ง โปรแกรมท่ี 8.5 ห น้ า 188
ตวั อยา่ งโปรแกรมท่ี 8.5 import CalArea Program Example 8.5: calling CalArea Area 1 # Calling package CalArea 2 import CalArea # import package CalArea 3 print(\"Area of squre :\",CalArea.squre(2.5, 2.5)) 4 print(\"Area of rectangle :\",CalArea.rectangle(2.5, 3.5)) 5 print(\"Area of triangle :\",CalArea.triangle(3, 2.5)) 6 print(\"Area of equilateral :\",CalArea.equilateral(2.5)) Area of squre : 6.25 Area of rectangle : 8.75 OUTPUT Area of triangle : 3.75 Area of equilateral : 10.825317547305481 จากโปรแกรมตวั อยา่ งท่ี 8.5 บรรทดั ท่ี 2 โปรแกรมทาการ import แพก็ เกจชอ่ื CalArea เขา้ มา ทางาน จากนนั้ ในบรรทดั ท่ี 3, 4, 5 และ 6 ทดสอบเรยี กฟังชนั ทอ่ี ย่ภู ายในแพก็ เกจดงั กลา่ ว โดยผใู้ ชต้ อ้ ง ทราบดว้ ยว่าแต่ละฟังชนั ตอ้ งการอารก์ วิ เมนตใ์ นการทางานกต่ี วั อะไรบา้ ง ผลลพั ธจ์ ากการเรยี กใชฟ้ ังชนั แสดงในตวั อยา่ งขา้ งบน Caution! ระวงั ในไดเรคทรอรที ส่ี รา้ งเป็นแพค็ เกจ (Package) จะตอ้ งประกอบดว้ ย แฟ้ม (โมดลู ) ทม่ี นี ามสกุล *.py และ __init__.py โดยตอ้ งสะกดชอ่ื แฟ้ม __init__ ใหถ้ กู ตอ้ งเสมอ สรปุ การสร้างและใช้งานแพก็ เกจ 1. สรา้ งโมดลู ทป่ี ระกอบไปดว้ ยฟังชนั ต่างๆ ทผ่ี เู้ ขยี นโปรแกรมตอ้ งการ เช่น โมดลู CalAreaRectagle ประกอบดว้ ยฟังชนั คานวณพน้ื ทส่ี เ่ี หลย่ี มดา้ นเท่า (Squre) ผนื ผา้ (Rectangle) เป็นตน้ เสรจ็ แลว้ บนั ทกึ แฟ้มเป็นชอ่ื CalAreaRectagle.py 2. สรา้ งแฟ้มเพอ่ื กาหนดคา่ คอนฟิกใหก้ บั แพก็ เกจ ชอ่ื __init__.py (ตอ้ งใชช้ ่อื น้เี ท่านัน้ และตอ้ ง สะกดช่อื แฟ้มใหถ้ ูกตอ้ งดว้ ย) ภายในแฟ้มใหท้ าการ import โมดลู และฟังชนั ทต่ี อ้ งการใช้ งาน เช่น from .CalAreaRectangle import squre, rectangle เป็นตน้ 3. สรา้ งไดเรคทรอรเี พ่อื ทาเป็นแพก็ เกจสาหรบั โมดลู ทส่ี รา้ งขน้ึ โดยตงั้ ชอ่ื ไดเรคทรอรใี ห้ สอดคลอ้ งกบั โมดลู ทส่ี รา้ ง ในตวั อยา่ งน้ีจะสรา้ งไดเรคทรอรชี ่อื CalArea จากนนั้ ใหท้ าการ คดั ลอกแฟ้ม CalAreaRectagle.py และ __init__.py เขา้ ไปในไดเรคทรอรที ส่ี รา้ งขน้ึ (ถา้ มี มากกว่า 1 แฟ้มใหค้ ดั ลอกเขา้ ไปทงั้ หมด) 4. เขยี นโปรแกรมทดสอบใชง้ านแพก็ เกจ โดยใชค้ าสงั่ import เขา้ มาทางาน เชน่ import CalArea # import package CalArea print(\"Area of squre :\", CalArea.squre(2.5, 2.5)) # calling the method in module จบบทท่ี 8 ห น้ า 189
บทท่ี 9 การจดั การข้อผิดพลาด (Handling Exceptions) 1. ข้อผิดพลาด (Exceptions) คืออะไร? ขอ้ ผดิ พลาด คอื เหตุการณ์ทเ่ี กดิ ขน้ึ ขณะโปรแกรมกาลงั ประมวลผลและสง่ ผลใหเ้ กดิ การ ขดั จงั หวะ หรอื รบกวนการประมวลผลคาสงั่ ปกตขิ องโปรแกรม โดยทวั่ ไปแลว้ ความผดิ พลาดสามารถ แบ่งออกเป็น 2 ประเภท คอื ความผดิ พลาดขณะคอมไพล์ (Compile-Time Errors) หรอื Syntax Error และความผดิ พลาดขณะโปรแกรมกาลงั ทาการประมวลผล (Run- Time-Errors) 1) ความผดิ พลาดขณะคอมไพล์ เกดิ ขน้ึ จากผเู้ ขยี นโปรแกรมไมป่ ฏบิ ตั ติ ามขอ้ กาหนดตามไวยกรณ์ ของภาษา เช่น สะกดประโยคคาสงั่ ผดิ พลาด ประกาศตวั แปรทเ่ี หมอื นกบั คาสงวน เป็นตน้ ลกั ษณะความผดิ พลาดแบบน้ผี เู้ ขยี นโปรแกรมจะพบเมอ่ื ทาการสงั่ คอมไพลโ์ ปรแกรม ถา้ ไมม่ ี การแกไ้ ขขอ้ ผดิ พลาดเหลา่ น้กี ่อน โปรแกรมจะไมส่ ามารถทางานได้ 2) ความผดิ พลาดขณะทาการประมวลผล สามารถจาแนกไดเ้ ป็น 2 สาเหตุใหญ่ๆ คอื ความ ผดิ พลาดจากวธิ กี ารคดิ (Program Logic) และความผดิ พลาดทเ่ี กดิ จากสภาวะแวดลอ้ มของการ ทางานไมส่ มบูรณ์ ความผดิ พลาดจากวธิ กี ารคดิ คอื ผเู้ ขยี นโปรแกรมเกดิ ความเขา้ ใจผดิ เกย่ี วกบั กระบวนการทางานของโปรแกรม เชน่ โปรแกรมทาการหารดว้ ยศูนย์ โปรแกรมสงั่ อ่าน แฟ้มแต่ไมป่ รากฎแฟ้มดงั กลา่ วในระบบ เป็นตน้ (ในสว่ นน้ผี เู้ ขยี นโปรแกรมสามารถ บรหิ ารจดั การได้ โดยใชค้ าสงั่ try…except) ความผดิ พลาดทเ่ี กดิ จากสภาวะแวดลอ้ มการทางานไมส่ มบรู ณ์ เชน่ หน่วยความจาไม่ เพยี งพอต่อการทางาน ระบบเครอื ขา่ ยไมพ่ รอ้ มใชง้ าน พน้ื ทท่ี เ่ี กบ็ ขอ้ มลู เตม็ เป็นต้น โดยปกตเิ มอ่ื โปรแกรมทเ่ี ขยี นขน้ึ เกดิ ขอ้ ผดิ พลาดอยา่ งใดอยา่ งหน่ึง ไพธอนจะจดั การความผดิ พลาด เหลา่ นนั้ ทนั ที เรยี กกระบวนการน้วี า่ การจดั การขอ้ ผดิ พลาด (Exceptions handling) แต่ถา้ ไมส่ ามารถ จดั การความผดิ พลาดเหลา่ นนั้ ได้ ไพธอนจะหยดุ การทางานของโปรแกรมเหล่านนั้ ทนั ที สาหรบั การ บรหิ ารจดั การความผดิ ปกตทิ ไ่ี มไ่ ดค้ าดการณ์ไว้ ไพธอนไดจ้ ดั เตรยี มคาสงั่ ไวใ้ ห้ 2 วธิ คี อื การจดั การ ขอ้ ผดิ พลาด (Exceptions handling) และการยนื ยนั ในสมมตฐิ าน (Assertions) ห น้ า 190
2. การจดั การข้อผิดพลาด (Exceptions handling) คณุ ลกั ษณะทส่ี าคญั อยา่ งมากสาหรบั การเขยี นโปรแกรมคอื ความคงทนของโปรแกรม โปรแกรมทม่ี คี วามคงทนจะไมล่ ม้ เหลวหรอื ยตุ กิ ารทางาน แมใ้ นขณะทเ่ี กดิ ขอ้ ผดิ พลาดขน้ึ จากความ ผดิ พลาดของผใู้ ช้ หรอื จากสง่ิ แวดลอ้ มอ่นื ๆ เพ่อื ใหโ้ ปรแกรมสามารถทนต่อสภาพความลม้ เหลว ในขณะทางานได้ ไพธอนไดจ้ ดั เตรยี มคาสงั่ ในการจดั การความผดิ พลาดไว้ โดยมรี ปู แบบคาสงั่ ดงั น้ี try: normal statement(s) except Exception 1: exception statement(s) except Exception 2: exception statement(s) ........... except Exception n: exception statement(s) else: normal statement(s) เงอ่ื นไขการใชค้ าสงั่ try…except มดี งั น้ี โปรแกรมตรงสว่ นทผ่ี เู้ ขยี นโปรแกรมคาดว่าอาจจะเกดิ ขอ้ ผดิ พลาดขน้ึ ไดใ้ นอนาคต (normal statement(s)) ใหใ้ ชค้ าสงั่ try ครอบไว้ คาสงั่ try จะทางานรว่ มกบั except เสมอ โดยคาสงั่ except สามารถใชง้ านไดม้ ากกวา่ 1 ครงั้ เน่อื งจากการตรวจจบั ความผดิ พลาดทเ่ี กดิ ขน้ึ มไี ดห้ ลายกรณี ผเู้ ขยี นโปรแกรมสามารถแสดงขอ้ ผดิ พลาดของโปรแกรมไดเ้ อง โดยกาหนดไวห้ ลงั คาสงั่ except (exception statement(s)) เชน่ except IOError: print (\"Error: can\\'t find file or read data\") ไพธอนออกแบบใหผ้ เู้ ขยี นโปรแกรมสามารถใชค้ าสงั่ else ปิดทา้ ยคาสงั่ try…except ได้ สาหรบั คาสงั่ else จะทางานกต็ ่อเมอ่ื โปรแกรมไม่มขี อ้ ผดิ พลาดใดๆ เกดิ ขน้ึ ตวั อยา่ งโปรแกรมท่ี 9.1 แสดงตวั อยา่ งการทางานของ try…except Program Example 9.1: try...except 1 # Try...except first program 2 try: ห น้ า 191
3 fh = open(\"myfile\", \"w\") 4 fh.write(\"This is my file for exception handling!!\") 5 except IOError: 6 print (\"Error: can\\'t find file or read data\") 7 else: 8 print (\"Written content in the file successfully\") 9 fh.close() Written content in the file successfully OUTPUT จากโปรแกรมตวั อยา่ งท่ี 9.1 แสดงตวั อยา่ งการใชง้ าน try…except บรรทดั ท่ี 2 โปรแกรม ประกาศคาสงั่ try: เพอ่ื ทาหน้าทต่ี รวจจบั ความผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ กบั การเปิดแฟ้มขอ้ มลู ในบรรทดั ท่ี 3 และสงั่ เขยี นแฟ้มในบรรทดั ท่ี 4 จากตวั อยา่ งโปรแกรมทาการเปิดแฟ้มเพ่อื เขยี น (\"w\") ชอ่ื myfile และเขยี นขอ้ ความลงในแฟ้มคอื “This is my file for exception handling!!” ลงในแฟ้มดงั กลา่ ว บรรทดั ท่ี 5 (except) เป็นคาสงั่ เพ่อื จดั การกบั ความผดิ พลาดทเ่ี กดิ ขน้ึ โดยปกตกิ ารเปิดแฟ้มจะตอ้ งทาการเชอ่ื มต่อ กบั Standard IO คอื ฮารด์ ดสิ ก์ ซง่ึ เป็นอุปกรณ์ทอ่ี าจจะเกดิ ขอ้ ผดิ พลาดขน้ึ ได้ ดงั นนั้ ในโปรแกรมจงึ ใช้ คาสงั่ try ทาการครอบสว่ นของโปรแกรมทต่ี ดิ ต่อกบั IO เอาไว้ ถา้ มขี อ้ ผดิ พลาดเกดิ ขน้ึ เช่น เปิดแฟ้ม ไมไ่ ด้ มโี ปรแกรมอ่นื ๆ ใชง้ านอยู่ เป็นตน้ โปรแกรมจะทาคาสงั่ ในส่วน except IOError แทน (บรรทดั ท่ี 5) โดยพมิ พข์ อ้ ความแสดงขอ้ ผดิ พลาดคอื “Error: can\\'t find file or read data” แตถ่ า้ โปรแกรมไม่มี ความผดิ พลาดใดๆ เกดิ ขน้ึ (เปิดแฟ้มและเขยี นขอ้ มลู ลงแฟ้มไดส้ าเรจ็ ) โปรแกรมจะทางานต่อหลงั คาสงั่ else (บรรทดั ท่ี 7) โดยพมิ พข์ อ้ ความคอื “Written content in the file successfully” และปิดแฟ้มขอ้ มลู ในบรรทดั ท่ี 9 ตามลาดบั จากตวั อยา่ งใหท้ าการทดสอบอ่าน-เขยี นแฟ้มใหมอ่ กี ครงั้ โดยในครงั้ น้ีกาหนดสทิ ธใิ ์ หอ้ ่าน แฟ้มขอ้ มลู ไดอ้ ยา่ งเดยี ว (บนระบบปฏบิ ตั กิ ารวนิ โดวส)์ โดยคลกิ ขวาท่แี ฟ้มช่อื myfile เล่อื ก Properties สว่ นของ Attributes ใหท้ าการคลกิ เลอื ก read-only เลอื ก Ok ดงั รปู ท่ี 9.1 ห น้ า 192
รปู ที่ 9.1 แสดงการกาหนดสทิ ธชิ ์ นดิ อ่านไดอ้ ยา่ งเดยี วใหก้ บั แฟ้มชอ่ื myfile จากนนั้ ใหท้ าการรนั โปรแกรมท่ี 9.1 อกี ครงั้ ผลลพั ธท์ ไ่ี ดค้ อื Error: can't find file or read data OUTPUT ขอ้ ผดิ พลาดเกดิ ขน้ึ จากโปรแกรมไมส่ ามารถเขยี นขอ้ มลู ลงไปในแฟ้มได้ เพราะแฟ้มถูกกาหนด สทิ ธใ์ หอ้ ่านไดอ้ ยา่ งเดยี ว เม่อื เกดิ ความผดิ พลาดขน้ึ โปรแกรมจะทางานหลงั คาสงั่ except IOError โดย พมิ พข์ อ้ ความ “Error: can't find file or read data” ออกทางจอภาพ และไมท่ าคาสงั่ ทอ่ี ยหู่ ลงั else (ไม่ จาเป็นตอ้ งปิดแฟ้มเพราะวา่ โปรแกรมไมส่ ามารถเปิดแฟ้มได)้ สาหรบั ความผดิ พลาดทเ่ี กดิ จากการป้อนขอ้ มลู ทางแป้นพมิ พ์ เช่น ผใู้ ชง้ านป้อนขอ้ มลู ผดิ ประเภท กจ็ ะสง่ ผลทาใหเ้ กดิ ขอ้ ผดิ พลาดได้ เชน่ >>> n = int(input(\"Please enter a number: \")) Please enter a number: 23.5 #invalid data type Traceback (most recent call last): File \"<stdin>\", line 1, in <module> ValueError: invalid literal for int() with base 10: '23.5' ตวั อยา่ งโปรแกรมท่ี 9.2 แสดงการใช้ try…except กบั การจดั การขอ้ ผดิ พลาดจากแป้นพมิ พ์ Program Example 9.2: try...except with keyboard 1 # Try...except with keyboard 2 while True: 3 try: 4 n = int(input(\"Please enter an integer: \")) 5 break 6 except ValueError: 7 print(\"No valid integer! Please try again ...\") 8 print(\"Great, you successfully entered an integer!\") ห น้ า 193
Please enter an integer: 5.6 No valid integer! Please try again ... OUTPUT Please enter an integer: 4 Great, you successfully entered an integer! จากตวั อยา่ งโปรแกรมท่ี 9.2 บรรทดั ท่ี 2 โปรแกรมทาการวนลปู แบบไม่รจู้ บ เพราะเง่อื นไขท่ี while ตรวจสอบเป็นจรงิ เสมอ บรรทดั ท่ี 3 โปรแกรมทาการตรวจจบั ความผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ กบั การป้อนขอ้ มลู จากแป้นพมิ พโ์ ดยใชค้ าสงั่ try บรรทดั ทดั ท่ี 4 โปรแกรมรบั ขอ้ มลู ผ่านแป้นพมิ พเ์ ป็นสตรงิ จากนนั้ ทาการแปลงเป็นเลขจานวนเตม็ ดว้ ยคาสงั่ int ถา้ ผใู้ ชง้ านป้อนขอ้ มลู เป็นเลขจานวนเตม็ โปรแกรม จะหยุดการทางานของคาสงั่ while ดว้ ยคาสงั่ break (บรรทดั ท่ี 5) และกระโดดไปทางานต่อในบรรทดั ท่ี 8 เพอ่ื พมิ พข์ อ้ ความว่า “Great, you successfully entered an integer!” พรอ้ มกบั จบการทางาน แต่ถา้ ผใู้ ชป้ ้อนขอ้ มลู ชนดิ อ่นื ๆ เช่น จานวนจรงิ ตวั อกั ษร เป็นตน้ โปรแกรมจะเกดิ ขอ้ ผดิ พลาดขน้ึ ส่งผลให้ โปรแกรมกระโดดไปทางานหลงั คาสงั่ except (บรรทดั ท่ี 6) ซง่ึ ประกาศไวว้ า่ เป็นความผดิ พลาดชนดิ ValueError (ขอ้ มลู ผดิ ประเภท) โปรแกรมจะสงั่ พมิ พข์ อ้ ความว่า “No valid integer! Please try again ...” (บรรทดั ท่ี 7) จากนนั้ โปรแกรมจะกลบั ไปรบั ขอ้ มลู จากแป้นพมิ พ์ใหมไ่ ปเรอ่ื ยๆ จนกวา่ ผใู้ ชง้ านจะ ป้อนขอ้ มลู ใหถ้ กู ตอ้ ง (เลขจานวนเตม็ เทา่ นนั้ ) การตรวจจบั ความผิดพลาดแบบไม่กาหนด Exceptions ในบางกรณผี เู้ ขยี นโปรแกรมไมท่ ราบชนิดของความผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ หรอื ไมต่ อ้ งการ กาหนดรายละเอยี ดของความผดิ พลาดทจ่ี ะเกดิ ขน้ึ เหล่านนั้ ไพธอนอนุญาตใหผ้ เู้ ขยี นโปรแกรมไม่ จาเป็นตอ้ งกาหนดชนดิ ของความผดิ พลาดได้ โดยมรี ปู แบบคาสงั่ ดงั น้ี try: normal statement(s) except: exception statement(s) else: normal statement(s) ตวั อยา่ งโปรแกรมท่ี 9.3 แสดงการตรวจจบั ขอ้ ผดิ พลาดทไ่ี มก่ าหนด Exception Program Example 9.3: undefined exception 1 # Try...except with no any exceptions 2 try: 3 fh = open(\"myfile\", \"w\") 4 fh.write(\"This is my file for exception handling!!\") 5 except: 6 print (\"IO Error with File\") 7 else: ห น้ า 194
8 print (\"Written content in the file successfully\") 9 fh.close() IO Error with File OUTPUT จากโปรแกรมท่ี 9.3 เป็นโปรแกรมทท่ี าหน้าทเ่ี ปิดแฟ้มเพ่อื เขยี นขอ้ มลู โดยกาหนดใหม้ กี าร ตรวจจบั ขอ้ ผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ จากการเปิดแฟ้มดว้ ยคาสงั่ try…except แต่ไมก่ าหนดชนิดความ ผดิ พลาดอนั ใดอนั หน่ึงไวห้ ลงั คาสงั่ except (บรรทดั ท่ี 5) เมอ่ื โปรแกรมเกดิ ความผดิ พลาดขน้ึ โปรแกรม สงั่ พมิ พข์ อ้ ความ “IO Error with File” ออกมาเท่านนั้ ซง่ึ การเขยี นโปรแกรมทด่ี ไี มค่ วรกระทาในลกั ษณะ เชน่ น้ี เพราะเมอ่ื โปรแกรมทางานผดิ พลาด ผเู้ ขยี นโปรแกรมจะคน้ หาสาเหตุของความผดิ พลาดไดย้ าก เพราะโปรแกรมแสดงขอ้ ความแบบทวั่ ๆ ไปไมไ่ ดเ้ จาะจงหรอื เชอ่ื มโยงกบั ปัญหาจรงิ ทเ่ี กดิ ขน้ึ การตรวจจบั ความผิดพลาดแบบหลาย Exceptions (Multiple exceptions) Try…except อนุญาตใหผ้ เู้ ขยี นโปรแกรมสามารถกาหนดเงอ่ื นไขการเกดิ ขอ้ ผดิ พลาดได้ มากกว่า 1 ชนดิ ไดภ้ ายใน try คาสงั่ เดยี วกนั แต่ขณะใดขณะหน่งึ จะมี exception เพยี งอนั เดยี วเท่านนั้ ท่ี จะไดถ้ กู ประมวลผล ซง่ึ มี 2 รปู แบบดงั น้ี แบบท่ี 1 กาหนด Exception แยกจากกนั try: normal statement(s) except Exception 1: exception statement(s) except Exception 2: exception statement(s) ........... except Exception n: แบบที่ 2 กาหนด Exception อยภู่ ายใตค้ าสงั่ except เดยี วกนั try: normal statement(s) except(Exception1[, Exception2[,...ExceptionN]]]): exception statement(s) ตวั อยา่ งโปรแกรมท่ี 9.4 แสดงการใชง้ าน Multiple exceptions ทงั้ 2 แบบ ห น้ า 195
Program Example 9.4: multiple exceptions 1 # Try...except with multiple exceptions 2 import sys 3 #This code for separating errors 4 try: 5 f = open('integers.txt') 6 s = f.readline() 7 i = int(s.strip()) 8 except IOError: 9 print(\"I/O error\") 10 except ValueError: 11 print(\"No valid integer in line.\") 12 except: 13 print(\"Unexpected error\") 14 15 #This code for combining errors 16 try: 17 fh = open(\"testfile\", \"w\") 18 fh.write(\"This is my file for exception handling!!\") 19 except(IOError, ValueError, SystemError): 20 print(\"Error: can\\'t find file or read data\") 21 else: 22 print(\"Written content in the file successfully\") 23 fh.close() No valid integer in line. Written content in the file successfully OUTPUT จากโปรแกรมท่ี 9.4 แสดงการใช้ try…except จดั การกบั exception หลายประเภท ในสว่ นแรก ของโปรแกรม (บรรทดั ท่ี 4 - 13) ทดสอบโดยการเปิดแฟ้มชอ่ื \"integer.txt\" แบบอ่านไดอ้ ยา่ งเดยี ว จากนนั้ ใชฟ้ ังชนั leadline() เพอ่ื อ่านขอ้ มลู ในแฟ้มจานวน 1 บรรทดั เกบ็ ไวใ้ นตวั แปร s บรรทดั ท่ี 6 โปรแกรมจะตดั ขอ้ ความว่างออกจากสตรงิ ดว้ ยฟังชนั strip() จากนนั้ สตรงิ จะถกู แปลงใหเ้ ป็นขอ้ มลู ชนดิ จานวนเตม็ ดว้ ยฟังชนั int() ความผดิ พลาดชนดิ IOError (บรรทดั ท่ี 8) เกดิ ขน้ึ จากโปรแกรมไมส่ ามารถ เปิดแฟ้มชอ่ื integers.txt เพ่อื อ่านได้ หรอื ไมม่ แี ฟ้มดงั กลา่ วอยใู่ นไดเรคทรอรปี ัจจบุ นั ความผดิ พลาด ชนดิ ValueError (บรรทดั ท่ี 10) เกดิ ขน้ึ จากแฟ้ม integers.txt ไม่มขี อ้ มลู ใดๆ หรอื ขอ้ มลู ไมใ่ ช่ตวั เลข (เกดิ จากคาสงั่ int(s.strip())) แต่ถา้ ขอ้ ผดิ พลาดไมอ่ ยใู่ น 2 ชนดิ แรก โปรแกรมจะทางานในสว่ น except: (บรรทดั ท่ี 12) โดยพมิ พข์ อ้ ความว่า “Unexpected error” สาหรบั สว่ นทส่ี องของโปรแกรม 9.4 (บรรทดั ท่ี 16 - 23) โปรแกรมทาการเปิดแฟ้มช่อื testfile.txt แบบเขยี นได้ (\"w\") เมอ่ื โปรแกรมเรมิ่ อ่านเขยี นแฟ้มและเกดิ ขอ้ ผดิ พลาดขน้ึ โปรแกรมจะ ทางานในบรรทดั ท่ี 19 ซง่ึ ไดร้ วมเอาความผดิ พลาดหลายชนดิ เขา้ ไวภ้ ายใน except เดยี วกนั คอื IOError, ValueError, SystemError เมอ่ื เกดิ ขอ้ ผดิ พลาดอยา่ งใดอยา่ งหน่งึ ขน้ึ ใน 3 ชนิดขา้ งตน้ โปรแกรมจะพมิ พข์ อ้ ความว่า “Error: can\\'t find file or read data” ห น้ า 196
การตรวจจบั ความผิดพลาดแบบ try…else..finally จากตวั อยา่ งทก่ี ลา่ วมาแลว้ ขา้ งตน้ เมอ่ื โปรแกรมเกดิ ขอ้ ผดิ พลาดขน้ึ โปรแกรมจะทางานในส่วน หลงั ของคาสงั่ except แต่ถา้ โปรแกรมทางานปกตไิ มม่ ขี อ้ ผดิ พลาดใดๆ จะประมวลผลหลงั คาสงั่ else (ถา้ ผเู้ ขยี นโปรแกรมประกาศคาสงั่ else ไวใ้ น try…except) แต่สาหรบั คาสงั่ try…finally จะมกี ารใชง้ าน ทแ่ี ตกต่างไปเลก็ น้อยคอื try…finally จะทางานทุกๆ ครงั้ แมว้ า่ โปรแกรมจะเกดิ ขอ้ ผดิ พลาด หรอื ไมก่ ็ ตาม ซง่ึ มรี ปู แบบคาสงั่ ดงั น้ี try: normal statement(s) finally: finally statement(s) สาหรบั การใช้ try…finally มขี อ้ กาหนดทค่ี วรทราบดงั น้ี สามารถใชค้ าสงั่ except รว่ มกบั คาสงั่ finally ได้ แต่ควรระวงั เรอ่ื งของความหมาย ในการแสดงผล และจาไวเ้ สมอวา่ เมอ่ื โปรแกรมทางานผดิ พลาดจะทางานหลงั คาสงั่ except และ finally แต่ถา้ โปรแกรมทางานปกติ โปรแกรมจะทาคาสงั่ หลงั finally สามารถใชค้ าสงั่ except รว่ มกบั finally และ else ได้ (ไมแ่ นะนาใหท้ า) แต่ตอ้ ง เรยี งลาดบั ใหถ้ ูกตอ้ ง โดยเรยี งลาดบั คาสงั่ ดงั น้ี try: normal statement(s) except: exception statement(s) else: else statement(s) finally: finally statement(s) ตวั อยา่ งโปรแกรมท่ี 9.5 แสดงตวั อยา่ งการใชง้ าน try…except, else และ finally รว่ มกนั Program Example 9.5: try...except, else and finally 1 # Try...except, else and finally 2 try: 3 fh = open(\"myfile\", \"w\") 4 fh.write(\"This is my file for exception handling!!\") 5 except: 6 print(\"IO Error with File\") 7 else: 8 print(\"Written content in the file successfully\") 9 finally: 10 print(\"This file is closed completely\") 11 fh.close() ห น้ า 197
Written content in the file successfully This file is closed completely OUTPUT IO Error with File This file is closed completely OUTPUT Traceback (most recent call last): File \"C:/Python33/exam9_5.py\", line 11, in <module> fh.close() NameError: name 'fh' is not defined จากโปรแกรมท่ี 9.5 บรรทดั ท่ี 3 โปรแกรมทาการเปิดแฟ้มแบบอ่านเขยี นได้ (\"w\")ถา้ โปรแกรม สามารถเปิดแฟ้มและเขยี นขอ้ มลู ลงแฟ้มได้ (บรรทดั ท่ี 4) โดยไมม่ ขี อ้ ผดิ พลาดใดๆ เกดิ ขน้ึ โปรแกรมจะ ประมวลผลหลงั คาสงั่ else (บรรทดั ท่ี 7) โดยพมิ พข์ อ้ ความว่า “Written content in the file successfully” จากนนั้ โปรแกรมจะทาคาสงั่ หลงั finally ต่อ (บรรทดั ท่ี 9) โดยพมิ พข์ อ้ ความว่า “This file is closed completely” พรอ้ มกบั ปิดแฟ้ม (บรรทดั ท่ี 11) และจบการทางานโดยสมบูรณ์ แต่ถา้ โปรแกรม ไมส่ ามารถอ่านหรอื เขยี นแฟ้มอยา่ งใดอย่างหน่งึ โปรแกรมจะทางานหลงั คาสงั่ except (บรรทดั ท่ี 5) โดยพมิ พข์ อ้ ความว่า “IO Error with File” เมอ่ื ทาคาสงั่ ดงั กลา่ วเสรจ็ โปรแกรมจะกระโดดไปทางานหลงั คาสงั่ finally โดยพมิ พข์ อ้ ความวา่ “This file is closed completely” พรอ้ มกบั ปิดแฟ้ม แต่โปรแกรมจะ เกดิ ขอ้ ผดิ พลาดคอื “NameError: name 'fh' is not defined” เน่อื งจากโปรแกรมตรงส่วน finally พยายามจะปิดแฟ้มซง่ึ ไมไ่ ดเ้ ปิดไว้ (เพราะเกดิ ขอ้ ผดิ พลาดก่อนเปิดแฟ้มไดใ้ นส่วนของคาสงั่ try) ทาให้ ไพธอนแจง้ เตอื นว่าแฟ้ม (fh) ดงั กลา่ วไมเ่ คยมกี ารประกาศไว้ 1 try 1 try 1 try statement(s) statement(s) statement(s) except: except: except: statement(s) statement(s) statement(s) (a) 2 finally: 2 else: statement(s) statement(s) (b) 3 finally: statement(s) (c) รปู ที่ 9.2 แสดงการใช้ try…except, else และ finally (กรณไี มเ่ กดิ ความผดิ พลาด) จากรปู ท่ี 9.2 แสดงการใช้ try…except, else และ finally เพ่อื ดกั จบั ขอ้ ผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ กบั โปรแกรม (a) โปรแกรมประมวลผลใน try แลว้ ไมเ่ กดิ ความผดิ พลาด โปรแกรมจะไมป่ ระมวลผล คาสงั่ except (b) โปรแกรมประมวลผลใน try แลว้ ไมเ่ กดิ ความผดิ พลาด โปรแกรมจะประมวลผลคาสงั่ finally และ (c) โปรแกรมประมวลผลใน try แลว้ ไมเ่ กดิ ความผดิ พลาด โปรแกรมจะประมวลผลทงั้ คาสงั่ else และ finally ห น้ า 198
1 try 1 try 1 try statement(s) statement(s) statement(s) 2 except: 2 except: 2 except: statement(s) statement(s) statement(s) 3 finally: else: statement(s) statement(s) (a) (b) 3 finally: statement(s) (c) รปู ท่ี 9.3 แสดงการใช้ try…except, else และ finally (กรณเี กดิ ความผดิ พลาด) จากรปู ท่ี 9.3 (a) โปรแกรมประมวลผลใน try แลว้ เกดิ ความผดิ พลาด โปรแกรมจะประมวลผล คาสงั่ except (b) โปรแกรมประมวลผลใน try แลว้ เกดิ ความผดิ พลาด โปรแกรมจะประมวลผลทงั้ คาสงั่ except และ finally (c) โปรแกรมประมวลผลใน try แลว้ เกดิ ความผดิ พลาด โปรแกรมจะประมวลผล คาสงั่ execpt และ finally ยกเวน้ คาสงั่ else การเขยี นโปรแกรมดว้ ยการใช้ try…except ทด่ี ไี มค่ วรใชค้ าสงั่ ทม่ี กี ารทางานซ้ากนั ในโปรแกรม เชน่ ถา้ ผเู้ ขยี นโปรแกรมใช้ finally แลว้ ไมค่ วรใช้ else อกี หรอื ถา้ ใชค้ าสงั่ except รว่ มกบั else แลว้ ก็ ไมค่ วรใช้ finally เช่นเดยี วกนั จากตวั อยา่ งโปรแกรมท่ี 9.6 แสดงการใช้ try…except ทง่ี า่ ยต่อการ ตคี วามหมายของโปรแกรม ตวั อยา่ งโปรแกรมท่ี 9.6 แสดงตวั อยา่ งการใชง้ าน try…except ทด่ี ี Program Example 9.6: good try...except 1 # How to use good try...except 2 try: 3 fh = open(\"myfile\", \"w\") 4 try: 5 fh.write(\"This is my test file for exception handling!!\") 6 finally: 7 print(\"Going to close the file\") 8 fh.close() 9 except IOError: 10 print(\"Error: can\\'t find file or read data\") Going to close the file Error: can't find file or read data OUTPUT จากโปรแกรมตวั อยา่ งท่ี 9.6 แสดงการใช้ try ซอ้ น try โดยคาสงั่ try ลาดบั ท่ี 1 (บรรทดั ท่ี 2) จะ ตรวจสอบการเปิดแฟ้มเพ่อื อ่านเขยี น ถา้ การเปิดแฟ้มเกดิ ขอ้ ผดิ พลาดขน้ึ (บรรทดั ท่ี 3) โปแกรมจะไป ทางานทห่ี ลงั คาสงั่ except IOError (บรรทดั ท่ี 9) โดยพมิ พข์ อ้ ความว่า “Error: can\\'t find file or read data” แต่ถา้ โปรแกรมทางานเป็นปกติ จะทางานในคาสงั่ ลาดบั ถดั ไป (บรรทดั ท่ี 5) คอื การเขยี นขอ้ ความ ห น้ า 199
ลงแฟ้มมขี อ้ ความวา่ “This is my test file for exception handling!!” เมอ่ื ขอ้ มลู ถกู เขยี นเสรจ็ เรยี บรอ้ ย แลว้ โปรแกรมจะพมิ พข์ อ้ ความวา่ “Going to close the file” (บรรทดั ท่ี 7) พรอ้ มกบั ปิดแฟ้มขอ้ มลู และ ยตุ กิ ารทางานของโปรแกรม สงั เกตวา่ try…except ทอ่ี ยดู่ า้ นนอกจะจดั การเกย่ี วกบั การเปิดแฟ้ม สว่ น try…finally ทอ่ี ยดู่ า้ นในจะจดั การความผดิ พลาดเกย่ี วกบั การเขยี นแฟ้ม โดย finally จะทาหน้าทป่ี ิดแฟ้ม เสมอ Note: try…finally จะทางานตลอดเวลา แมว้ ่าการทางานของโปรแกรมจะผดิ ปกตหิ รอื ไมก่ ็ ตาม ดงั นนั้ ถา้ โปรแกรมเกดิ ขอ้ ผดิ พลาดขน้ึ อาจจะไม่ทราบว่าเกดิ ขน้ึ หรอื ไมอ่ ยา่ งไร เพราะ โปรแกรมจะเขา้ ไปทางานในส่วน finally เสมอ เช่น ในโปรแกรมท่ี 9.6 ผเู้ ขยี นโปรแกรมจะไม่ ทราบเลยว่ามขี อ้ ผดิ พลาดทเ่ี กดิ ขน้ึ ขณะเขยี นขอ้ ความลงแฟ้มหรอื ไม่ เพราะโปรแกรมจะทา คาสงั่ finally เสมอ อารก์ ิวเมนตข์ อง Exception ไพธอนอนุญาตใหผ้ เู้ ขยี นโปรแกรมสามารถสรา้ งอารก์ วิ เมนต์เพ่อื รบั ขอ้ มลู เกย่ี วกบั ความ ผดิ พลาดหรอื ปัญหาทเ่ี กดิ ขน้ึ จากไพธอนคอมไพลเ์ ลอรไ์ ด้ โดยมรี ปู แบบคาสงั่ ดงั น้ี try: normal statement(s) except ExceptionType as Args: exception statement(s) จากรปู แบบคาสงั่ ขา้ งบน ExceptionType as คอื ชนิดของความผดิ ปกตทิ เ่ี กดิ ขน้ึ ในโปรแกรม ซง่ึ แสดงในรปู ท่ี 9.4 และ Args คอื ตวั แปรอารก์ วิ เมนต์ทผ่ี เู้ ขยี นโปรแกรมกาหนดขน้ึ เอง เพอ่ื สาเนา ขอ้ มลู ความผดิ ปกตจิ ากอ๊อปเจก็ ต์ ExceptionType ตวั อยา่ งการใชง้ านดงั โปรแกรมท่ี 9.7 ตวั อยา่ งโปรแกรมท่ี 9.7 แสดงตวั อยา่ งการใชง้ านอารก์ วิ เมนตข์ อง exception Program Example 9.7: except arguments 1 # Argument of Exception 2 # Define a function here. 3 def temp_convert(var): 4 try: 5 return int(var) 6 except ValueError as Args: 7 print (\"Argument doesn’t contain numbers\\n\", Args.args) 8 # Call above function here. 9 temp_convert(\"xyz\"); Argument does not contain numbers (\"invalid literal for int() with base 10: 'xyz'\") OUTPUT ห น้ า 200
จากโปรแกรมท่ี 9.7 แสดงการสรา้ งอารก์ วิ เมนตเ์ พ่อื รบั ขอ้ มลู ความผดิ พลาดจากไพธอน คอมไพลเ์ ลอร์ บรรทดั ท่ี 3 โปรแกรมประกาศฟังชนั ช่อื temp_convert ทาหน้าทแ่ี ปลงอ๊อปเจก็ ใดๆ ให้ เป็นชนดิ จานวนเตม็ (บรรทดั ท่ี 5) โดยมพี ารามเิ ตอร์ 1 ตวั คอื var บรรทดั ท่ี 4 โปรแกรมทาการตรวจจบั ความผดิ พลาดไว้ ในกรณที ไ่ี มส่ ามารถแปลงขอ้ มลู ไดส้ าเรจ็ โปรแกรมจะทางานในบรรทดั ท่ี 6 ซง่ึ ทาการ สาเนาความผดิ พลาดจากตวั แปรระบบคอื ValueError ไปเป็น Args ดว้ ยคาสงั่ as เมอ่ื ขอ้ ผดิ พลาด เกดิ ขน้ึ เช่น อ๊อปเจก็ var ไมเ่ ป็นจานวนเตม็ โปรแกรมจะพมิ พข์ อ้ ความว่า \"Argument doesn’t contain numbers\" พรอ้ มกบั ความผดิ พลาดทถ่ี กู สาเนาเกบ็ ไวใ้ นตวั แปร Args.args (เมอ่ื ตอ้ งการแสดงขอ้ มลู ผดิ พลาดในอารก์ วิ เมนต์ Args ใหใ้ ช้ .attribute เช่น Args.args) บรรทดั ท่ี 9 โปรแกรมทาการเรยี กฟังชนั temp_convert พรอ้ มคา่ คงทส่ี ตรงิ เป็นอารก์ วิ เมนต์ ใหก้ บั ฟังชนั ผลปรากฎวา่ ฟังชนั แสดงขอ้ ความ Argument does not contain numbers (\"invalid literal for int() with base 10: 'xyz'\") เพราะอารก์ วิ เมนตท์ ส่ี ่งเขา้ ไปใหฟ้ ังชนั ผดิ ประเภท (ตอ้ งการสตรงิ ทเ่ี ป็น ตวั เลขไมใ่ ช่ตวั อกั ษร) นนั่ เอง BaseException SystemExit Exception KeyboardInterrupt GeneratorExit DeprecationWarning StopIteration StandardError Warning PendingDeprecationWarning RuntimeWarning BufferError FloatingPointError SyntaxWarning UserWarning ArithmeticError OverflowError FutureWarning ImportWarning AssertionError ZeroDivisionError UnicodeWarning BytesWarning ImportError MemoryError IndexError LookupError KeyError EOFError AttributeError IOError WindowsError(Windows) EnvironmentError OSError VMSError(VMS) ReferenceError RuntimeError IndentationError TabError SyntaxError UnicodeDecodeError ValueError UnicodeError UnicodeEncodeError SystemError UnicodeTranslateError TypeError NameError UnboundLocalError รปู ท่ี 9.4 แสดงประเภทของ Exceptions ห น้ า 201
จากรปู ท่ี 9.4 คลาส Exception เป็นคลาสหลกั ทส่ี าคญั ครอบคลมุ ความผดิ พลาดทเ่ี กดิ ขน้ึ เกอื บ ทงั้ หมด โดยคลาส StandardError เป็นคลาสลกู ทส่ี บื ทอดคณุ สมบตั มิ าจากคลาส Exception คลาสน้ที า หน้าทด่ี แู ลเกย่ี วกบั ความผดิ พลาดพน้ื ฐานทพ่ี บเจอบอ่ ยๆ ในการเขยี นโปรแกรม เช่น ArithmeticError ซง่ึ เป็นความผดิ พลาดทเ่ี กย่ี วกบั การประมวลผลทางคณิตศาสตร์ MemoryError เป็นความผดิ พลาด เกย่ี วกบั การอา้ งถงึ หน่วยความจา RuntimeError เป็นความผดิ พลาดทเ่ี กดิ ขน้ึ ขณะโปรแกรมกาลงั ทางาน เช่น คน้ หาแฟ้มไมพ่ บ ชนิดตวั แปรผดิ พลาด เป็นตน้ SyntaxError คอื ความผดิ พลาดของการ เขยี นโปรแกรมผดิ ไวยกรณ์ และ SystemError คอื ความผดิ พลาดเกย่ี วกบั ระบบ เช่น พน้ื ท่ี หน่วยความจาในดสิ กเ์ ตม็ ระบบเครอื ขา่ ยไมส่ ามารถเช่อื มต่อได้ เป็นตน้ สาหรบั ชนิดและความหมาย ของความผดิ พลาดต่างๆ สามารถอ่านเพมิ่ เตมิ ไดจ้ าก Python Library (http://docs.python.org/3.1/library/exceptions.html) การตรวจจบั ความผิดพลาดด้วยคาสงั่ Raising Raising คอื คาสงั่ ทไ่ี พธอนอนุญาตใหผ้ เู้ ขยี นโปรแกรมสามารถสรา้ งขอ้ ความแจง้ เตอื นความ ผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ ไดด้ ว้ ยตนเอง ซง่ึ คาสงั่ ดงั กล่าวจะทาหน้าท่ี 2 อยา่ งคอื สรา้ ง Exception object เพอ่ื ใชส้ าหรบั อา้ งองิ กบั ความผดิ พลาดทไ่ี พธอนสรา้ งไว้ (Built-in exception) และการโยนความ ผดิ พลาดไปยงั โปรแกรมทเ่ี รยี กใชง้ าน สาหรบั การใชง้ าน raising มรี ปู แบบคอื raise [Exception [, args [, traceback]]] raise คอื คาสงั่ ตรวจจบั ความผดิ พลาด Exception คอื ชนดิ ของความผดิ พลาดทเ่ี กดิ ขน้ึ เชน่ NameError, IOError เป็นตน้ ซง่ึ อารก์ วิ เมนตด์ งั กลา่ วจะกาหนดหรอื ไมก่ ไ็ ด้ (เพราะอยใู่ นเครอ่ื งหมาย […]) args เป็นอารก์ วิ เมนต์ของ exception ถา้ ไมไ่ ดก้ าหนดไวไ้ พธอนจะถอื ว่าเป็นคา่ เป็น None อารก์ วิ เมนต์ traceback เป็นออ็ ปชนั ทใ่ี ชส้ าหรบั แสดงความผดิ พลาดแบบยอ้ นกลบั (ตน้ เหตุของปัญหา) สาหรบั ตวั อยา่ งการใชง้ าน raising แสดงดงั โปรแกรมท่ี 9.8, 9.9 ตวั อยา่ งโปรแกรมท่ี 9.8 แสดงตวั อยา่ งการใชง้ าน raise Program Example 9.8: raise 1 # Raising exception example 1 2 def functionName(level): 3 if level < 1: 4 raise (\"Invalid level!\", level) 5 print(\"The code would not be executed\") 6 print(\"Good Bye!\") 7 8 functionName(5) 9 functionName(0) ห น้ า 202
Good Bye! OUTPUT Traceback (most recent call last): File \"C:\\Python34\\exam9_8.py\", line 9, in <module> functionName(0) File \"C:\\Python34\\exam9_8.py\", line 4, in functionName raise (\"Invalid level!\", level) TypeError: exceptions must derive from BaseException จากโปรแกรมตวั อยา่ งท่ี 9.8 แสดงการใชค้ าสงั่ raising เพอ่ื สรา้ งขอ้ ความแจง้ เตอื นความ ผดิ พลาดทผ่ี ใู้ ชก้ าหนดขน้ึ เอง บรรทดั ท่ี 2 โปรแกรมประกาศฟังชนั ชอ่ื ว่า functionName ทาหน้าท่ี ตรวจสอบระดบั สทิ ธใ์ นการประมวลผล ถา้ ระดบั สทิ ธ์ (level) น้อยกวา่ 1 จะไมอ่ นุญาตใหป้ ระมวลผล ฟัง ชนั ดงั กล่าวมพี ารามเิ ตอร์ 1 ตวั คอื level (ระดบั สทิ ธกิ ์ ารประมวลผล) บรรทดั ท่ี 3 โปรแกรมใช้ if ในการ ตรวจสอบเงอ่ื นไขวา่ ถา้ level น้อยกว่า 1 หรอื ไม่ ถา้ ใช่โปรแกรมจะสรา้ งขอ้ ความแจง้ เตอื นความ ผดิ พลาดใหมโ่ ดยใชค้ าสงั่ raise (บรรทดั ท่ี 4) โดยพมิ พข์ อ้ ความวา่ \"Invalid level!\" พรอ้ มกบั คา่ ในตวั แปร level ไปใหก้ บั ผเู้ รยี กใชง้ านและจบโปรแกรมทนั ทโี ดยไม่ประมวลผลคาสงั่ ในบรรทดั ท่ี 5 ซง่ึ พมิ พ์ ขอ้ ความแจง้ เตอื นว่า \"The code would not be executed\" แต่ถา้ level มคี า่ มากกวา่ 1 โปรแกรมจะ พมิ พข์ อ้ ความว่า \"Good Bye!\" และยตุ กิ ารทางานของโปรแกรม บรรทดั ท่ี 8 โปรแกรมเรยี ก functionName พรอ้ มคา่ คงทเ่ี ป็นอารก์ วิ เมนต์มคี า่ เท่ากบั 5 ผลลพั ธ์ ทไ่ี ดจ้ าก functionName คอื ขอ้ ความวา่ \"Good Bye!\" บรรทดั ท่ี 9 ทดสอบเรยี กฟังชนั เดมิ อกี ครงั้ พรอ้ ม กบั คา่ คงทเ่ี ป็นอารก์ วิ เมนตม์ คี า่ เท่ากบั 0 ผลลพั ธท์ ไ่ี ดค้ อื ขอ้ ความผดิ พลาดทเ่ี กดิ จากคาสงั่ raise พรอ้ ม กบั ขอ้ ผดิ พลาดทไ่ี พธอนสามารถตรวจจบั ได้ ดงั แสดงในตวั อยา่ งขา้ งบน ตวั อยา่ งโปรแกรมท่ี 9.9 แสดงตวั อยา่ งการใชค้ าสั่ raise อกี แบบหน่งึ Program Example 9.9: other rise exam 1 # Raising exception example 2 2 try: 3 f = open(\"myfile\",\"w\") 4 f.write(\"This is my test file for exception handling!!\") 5 except(IOError, ValueError): 6 print(\"An I/O error or a ValueError occurred\") 7 raise OSError(\"Permission denied\") 8 except: 9 print(\"An unexpected error occurred\") 10 raise 11 else: 12 f.close() 13 print(\"Myfile was closed!!\") 14 finally: 15 print(\"Program has finished\") # While Myfile attribute can read-write Myfile was closed!! OUTPUT Program has finished ห น้ า 203
# While Myfile attribute can read-only An I/O error or a ValueError occurred Program has finished Traceback (most recent call last): File \"C:/Python33/exam9_9.py\", line 4, in <module> f = open(\"myfile\", \"w\") PermissionError: [Errno 13] Permission denied: 'myfile' During handling of the above exception, another exception occurred: Traceback (most recent call last): File \"C:/Python33/exam9_9.py\", line 8, in <module> raise OSError(\"Permission denied\") OSError: Permission denied จากโปรแกรมตวั อยา่ งท่ี 9.9 แสดงการทางานของคาสงั่ raise อกี รปู แบบหน่งึ เรม่ิ ต้นจาก บรรทดั ท่ี 3 โปรแกรมทาการเปิดแฟ้มชอ่ื Myfile เพอ่ื เขยี น (\"w\") ถา้ โปรแกรมสามารถเขยี นขอ้ ความวา่ \"This is my test file for exception handling!!\" ลงแฟ้มไดส้ าเรจ็ (บรรทดั ท่ี 4) โปรแกรมจะไป ประมวลผลคาสงั่ หลงั else ในบรรทดั ท่ี 12 คอื ปิดแฟ้มพรอ้ มกบั พมิ พข์ อ้ ความว่า “Myfile was closed!!” ออกทางจอภาพ (บรรทดั ท่ี 13) จากนนั้ โปรแกรมจะประมวลผลคาสงั่ finally ต่อในบรรทดั ท่ี 14 โดย พมิ พข์ อ้ ความว่า “Program has finished” และยตุ กิ ารทางานของโปรแกรม แต่ถา้ โปรแกรมไมส่ ามารถ เขยี นขอ้ มลู ลงแฟ้ม Myfile ได้ (ทดสอบโดยการคลกิ ขวาทแ่ี ฟ้ม Myfile แลว้ เลอื ก attribute เป็น read- only) โปรแกรมจะเกดิ ขอ้ ผดิ พลาดขน้ึ ถา้ เกดิ ความผดิ พลาดเป็นชนิด IOError และ ValueError (บรรทดั ท่ี 5) โปรแกรมจะไป ประมวลผลหลงั คาสงั่ except (IOError, ValueError) ในบรรทดั ท่ี 6 โดยพมิ พข์ อ้ ความวา่ “An I/O error or a ValueError occurred” ต่อจากนนั้ บรรทดั ท่ี 7 โปรแกรมจะทาการประมวลผลคาสงั่ raise โดยกรอง เอาเฉพาะความผดิ พลาดชนิด OSError ไว้ ถา้ โปรแกรมเกดิ ความผดิ พลาดตามชนดิ ทร่ี ะบุไว้ (OSError) จะพมิ พข์ อ้ ความว่า “Permission denied” และจะประมวลผลคาสงั่ finally เป็นอนั ดบั สดุ ทา้ ย แต่ถา้ ความผดิ พลาดทเ่ี กดิ ขน้ึ ไมใ่ ช่ทงั้ IOError และ ValueError โปรแกรมจะประมวลผลทค่ี าสงั่ except (บรรทดั ท่ี 8) โดยพมิ พข์ อ้ ความว่า “An unexpected error occurred” (บรรทดั ท่ี 9) พรอ้ มกบั สงั่ ใหไ้ พธอนแสดงความผดิ พลาดทเ่ี กดิ ขน้ึ จรงิ ๆ ในระบบดว้ ยคาสงั่ raise (บรรทดั ท่ี 10) อกี ครงั้ สดุ ทา้ ย โปรแกรมจะทางานหลงั คาสงั่ finally (จะทางานทุกครงั้ แมว้ า่ จะเกดิ หรอื ไมเ่ กดิ ขอ้ ผดิ พลาดใดๆ กต็ าม) โดยไมป่ ระมวลผลคาสงั่ else ตวั อยา่ งโปรแกรมท่ี 9.10 แสดงการตรวจจบั ความผดิ พลาดทเ่ี กดิ จากจานวนเตม็ ทน่ี ้อยกวา่ 0 Program Example 9.10: detecting zero number 1 # Raising exception example 3 2 def f(x): ห น้ า 204
3 return g(x) + 1 4 def g(x): 5 if x < 0: raise (ValueError, (\"I can't settle with a negative number.\")) 6 else: return 5 7 try: 8 print (f(3)) 9 print (f(-5)) 10 except ValueError: 11 print (\"That value was invalid.\") 6 OUTPUT Traceback (most recent call last): File \"C:/Python33/exam9_10.py\", line 11, in <module> print (f(-5)) File \"C:/Python33/exam9_10.py\", line 3, in f return g(x) + 1 File \"C:/Python33/exam9_10.py\", line 6, in g if x < 0: raise (ValueError, (\"I can't settle with a negative number.\")) TypeError: exceptions must derive from BaseException การสร้าง Exception ขึน้ มาใช้งานเอง (User-defined exceptions) ไพธอนอนุญาตใหผ้ เู้ ขยี นโปรแกรมสามารถสรา้ ง exception ขน้ึ มาใชง้ านเองได้ โดยการสบื ทอด คุณสมบตั มิ าจากคลาสทเ่ี ป็น built-in มาตรฐาน (standard built-in exceptions) ตวั อยา่ งเชน่ เมอ่ื ผเู้ ขยี น โปรแกรมเขยี นโปรแกรมเกย่ี วกบั ระบบเครอื ข่าย (Networking) และตอ้ งการสรา้ ง exception เกย่ี วกบั ความผดิ พลาดเก่ยี วกบั การส่อื สาร ผเู้ ขยี นโปรแกรมสามารถสบื ทอด exception จากคลาส RuntimeError ซง่ึ มรี ปู แบบการสบื ทอดดงั น้ี class NetworkError(RuntimeError): def __init__(self, arg): self.args = arg สาหรบั การใชง้ าน class NetworkError มรี ปู แบบคอื try: raise Networkerror(\"Bad hostname\") except Networkerror as e: print(e.args) ('B', 'a', 'd', ' ', 'h', 'o', 's', 't', 'n', 'a', 'm', 'e') OUTPUT ห น้ า 205
จากตวั อยา่ งโปรแกรมขา้ งบน ใชค้ าสงั่ raise สาหรบั ตรวจจบั และบงั คบั ใหโ้ ปรแกรมพมิ พ์ ขอ้ ความ “Bad hostname” ขณะโปรแกรมทางานผดิ พลาด และใชต้ วั แปร e ในการสาเนาขอ้ มลู ทเ่ี กดิ ความผดิ พลาดมาแสดงผล 3. การยืนยนั ในสมมติฐาน (Assertions) Assertions คอื การทดสอบและยนื ยนั สมมตฐิ านเกย่ี วกบั โปรแกรมทไ่ี ดเ้ ขยี นไว้ ยกตวั อยา่ งเช่น กรณที ม่ี เี งอ่ื นไขในโปรแกรมทผ่ี เู้ ขยี นมนั่ ใจวา่ จะไมม่ โี อกาสเป็นเทจ็ ได้ (False) ผเู้ ขยี นโปรแกรมควรจะ วาง assertion เป็นจริง (True) เอาไว้ ถา้ ระหวา่ งการพฒั นาหรอื ใชง้ านโปรแกรมแลว้ เกดิ ความ ผดิ พลาดทเ่ี กดิ จาก Assertion error แสดงว่าโปรแกรมตรงตาแหน่งดงั กล่าวมกี ารทางานทผ่ี ดิ พลาด เกดิ ขน้ึ จาเป็นตอ้ งแกไ้ ขใหถ้ กู ตอ้ ง หรอื ถา้ จะพดู ใหส้ นั้ ๆ งา่ ยๆ คอื การกรอง (Fillter) ความถูกตอ้ งของ โปรแกรมในสว่ นทผ่ี เู้ ขยี นโปรแกรมกาหนดไวน้ นั่ เอง การวางตาแหน่งของ assertion ไวใ้ นโปรแกรม โดยปกตจิ ะวา่ งไวท้ จ่ี ดุ เรม่ิ ตน้ ของฟังชนั เพ่อื ตรวจสอบอนิ พตุ พารามเิ ตอร์ และวางไวห้ ลงั จากทเ่ี รยี กฟัง ชนั เพอ่ื ใชส้ าหรบั ตรวจสอบเอาตพ์ ตุ ทส่ี ่งกลบั มา assertion มรี ปู แบบคาสงั่ ดงั น้ี assert Expression[, Arguments] assert คอื คาสงั่ ทใ่ี ชต้ รวจสอบสมมตฐิ าน, Expression คอื เงอ่ื นไขทต่ี อ้ งการตรวจสอบ และ Arguments คอื ขอ้ มลู เกย่ี วกบั ความผดิ พลาด เมอ่ื ไพธอนแปลคาสงั่ มายงั บรรทดั ทว่ี าง assert เอาไว้ ไพธอนจะตรวจสอบเงอ่ื นไขทก่ี าหนดไว้ ว่าเป็นจรงิ หรอื ไม่ ถา้ เป็นจรงิ ไพธอนจะประมวลผลคาสงั่ ถดั ไป เหมอื นไมม่ อี ะไรเกดิ ขน้ึ (เหมอื นคาสงั่ pass) แต่ถา้ เงอ่ื นไขเป็นเทจ็ ไพธอนจะสรา้ งความผดิ พลาด AssertionError ออกมาใหผ้ เู้ ขยี นโปรแกรม ไดท้ ราบทนั ที โดยโยนความผดิ พลาดเกบ็ ไวใ้ น Arguments โปรแกรมเมอรส์ ามารถจบั ความผดิ พลาด ดงั กลา่ วดว้ ยคาสงั่ try…except ได้ แต่ถา้ ไมไ่ ดส้ รา้ งคาสงั่ ตรวจจบั ไว้ เมอ่ื เกดิ ขอ้ ผดิ พลาดจาก assert โปรแกรมจะหยดุ ทางาน และจะแสดงผลความผดิ พลาดแบบยอ้ นกลบั (trackback) ใหผ้ เู้ ขยี นโปรแกรม ไดท้ ราบ ข้อกาหนดในการใช้ assert วางคาสงั่ assert ไวใ้ นบรรทดั ทโ่ี ปรแกรมเมอรค์ ดิ ว่าจะเป็นจรงิ (True) เสมอ ถา้ เงอ่ื นไขเป็นเทจ็ ขณะทางาน assert จะสรา้ ง AssertionError ออกมา โปรแกรมเมอรส์ ามารถ disable การตรวจสอบได้ โดยทวั่ ไปการใช้ assert จะกระทาในชว่ งการพฒั นาโปรแกรม แต่หลงั จากทโ่ี ปรแกรม พฒั นาไดส้ มบรู ณ์หรอื ปลอดภยั แลว้ ควร disable คาสงั่ assert ดว้ ย ห น้ า 206
ประโยชน์ของ assert ใชเ้ พอ่ื ตรวจสอบสมมตฐิ านหรอื คดั กรองความผดิ พลาดของผเู้ ขยี นโปรแกรม ช่วยในการหาขอ้ ผดิ พลาดของโปรแกรม (bug) เพมิ่ ความมนั่ ใจวา่ โปรแกรมทใ่ี ชง้ านจะไมม่ ขี อ้ ผดิ พลาดหรอื มขี อ้ ผดิ พลาดน้อยทส่ี ุด ใชง้ านไดส้ ะดวกกวา่ try…except เน่อื งจากสามารถ disable การตรวจสอบของ assert ไดใ้ นขณะทโ่ี ปรแกรมทางาน (Run-time) โดยไมล่ ดทอนประสทิ ธภิ าพการทางานของ การประมวลผลลง ตาแหน่งที่นิยมวาง assert ไว้ ในฟังชนั (ดา้ นบนสดุ ของฟังชนั ) เพ่อื ตรวจสอบตวั แปรอนิ พตุ หลงั จากกลบั มาจากการเรยี กใชง้ านฟังชนั เพอ่ื ตรวจสอบคา่ ทส่ี ง่ กลบั จากฟังชนั วางแทนตาแหน่งของ comment ในโปรแกรม วางไวห้ ลงั คาสงั่ ทไ่ี ม่มคี าสงั่ default เช่น หลงั while, for เป็นตน้ วาง assert ไวใ้ นลปู หรอื เงอ่ื นไขทไ่ี มม่ โี อกาสจะเกดิ ขน้ึ (อาจจะไมเ่ กดิ ขน้ึ ในปัจจบุ นั แต่ อาจจะเกดิ ขน้ึ ไดใ้ นอนาคต) คาแนะนาเพิ่มเติมอื่นๆ เก่ียวกบั การใช้งาน assert Expression ของ assert ตอ้ งไมม่ ผี ลกระทบกบั การทางานในส่วนอ่นื ๆ ของโปรแกรม (side effect) ใหเ้ พมิ่ assert ขณะกาลงั เขยี นโปรแกรม ไมค่ วรเขยี นหลงั จากเขยี นโปรแกรมเสรจ็ แลว้ (เพราะขอ้ สงสยั อาจจะหายไปดว้ ยเมอ่ื เวลาผา่ นไป) ใช้ assert ไดม้ ากเท่าทต่ี อ้ งการ ไมต่ อ้ งกลวั วา่ จะมากเกนิ ไป ขอใหส้ ามารถตรวจสอบ ความผดิ พลาดของโปรแกรมไดม้ ากทส่ี ุด (เป้าหมายคอื โปรแกรมไม่มี bug เลย) ไมต่ อ้ งหว่ งเรอ่ื งประสทิ ธภิ าพการทางานทจ่ี ะลดลง เน่อื งจากสามารถ disable คาสงั่ asset ได้ Exception ใชก้ บั สงิ่ ทค่ี ดิ วา่ จะเกดิ ความผดิ พลาด เมอ่ื ความผดิ พลาดเกดิ ขน้ึ แลว้ จะตอ้ ง มวี ธิ แี กไ้ ข แต่ assertion ใชก้ บั สงิ่ ทต่ี อ้ งไมเ่ กดิ ขน้ึ ถา้ เกดิ ขน้ึ แสดงว่าผดิ พลาดคอ่ นขา้ ง รา้ ยแรง Exception เป็นการเสรมิ ใหโ้ ปรแกรมมคี วามคงทน ไมล่ ม้ เหลวงา่ ยๆ (Robustness) แต่ assert เป็นการสรา้ งความเช่อื มนั่ (Reliability) ใหก้ บั โปรแกรมทเ่ี ขยี นขน้ึ ห น้ า 207
ตวั อยา่ งโปรแกรมท่ี 9.11 การวาง assert preconditions ไวใ้ นฟังชนั เพ่อื ตรวจสอบอนิ พตุ พารามเิ ตอร์ Program Example 9.11: assert preconditions 1 # Assert preconditions 2 def DIV(x, y): 3 assert (y != 0), \"Cann't divide by zero!!!\" 4 return x / y 5 print (DIV(5, 3)) 6 print (DIV(5, 0)) 1.6666666666666667 Traceback (most recent call last): OUTPUT File \"C:/Python34/exam9_11.py\", line 7, in <module> print (DIV(5, 0)) File \"C:/Python34/exam9_11.py\", line 3, in DIV assert (y != 0), \"Cann't divide by zero!!!\" AssertionError: Cann't divide by zero!!! จากโปรแกรมท่ี 9.11 เรมิ่ ต้นบรรทดั ท่ี 2 โปรแกรมประกาศฟังชนั ชอ่ื DIV() ทาหน้าทค่ี านวณ การหารของเลข 2 จานวน โดยมพี ารามเิ ตอร์ 2 ตวั คอื x และ y บรรทดั ท่ี 3 โปรแกรมทาการตรวจสอบ สมมตฐิ านดว้ ยคาสงั่ assert วา่ y ตอ้ งไมเ่ ท่ากบั 0 จงึ จะยอมใหโ้ ปรแกรมทางานต่อไปได้ แต่ถา้ y เป็น 0 โปรแกรมจะพมิ พข์ อ้ ความวา่ “Cann't divide by zero!!!” พรอ้ มกบั แสดงขอ้ ผดิ พลาดทงั้ หมดและยตุ ิ การทางานของโปรแกรม สาหรบั ในกรณที ่ี y ไมเ่ ท่ากบั 0 โปรแกรมจะประมวลผลคาสงั่ หาร x/y (บรรทดั ท่ี 4) และส่งผลลพั ธจ์ ากการหารกลบั ไปยงั ผูเ้ รยี กใชง้ าน บรรทดั ท่ี 5 โปรแกรมเรยี กฟังชนั DIV พรอ้ มกบั ค่าคงทเ่ี ป็นอารก์ วิ เมนตเ์ ท่ากบั 5 และ 3 ตามลาดบั ผลลพั ธท์ ไ่ี ดจ้ ากฟังชนั DIV คอื 1.666 ซง่ึ เป็นผลลพั ธท์ ถ่ี ูกตอ้ งและไมม่ ขี อ้ ผดิ พลาด เน่อื งจากค่าคงท่ี 3 จะถูกกาหนดใหก้ บั พารามเิ ตอร์ y และมคี า่ ไมเ่ ท่ากบั 0 บรรทดั ท่ี 6 โปรแกรมเรยี กฟังชนั DIV อกี ครงั้ พรอ้ มกบั คา่ คงทเ่ี ป็นอารก์ วิ เมนตเ์ ท่ากบั 5 และ 0 ตามลาดบั ผลลพั ธท์ ไ่ี ดจ้ ากฟังชนั DIV คอื ขอ้ ความผดิ พลาดทถ่ี ูกจบั ไดโ้ ดย assert และขอ้ ความ ผดิ พลาดทไ่ี พธอนสรา้ งขน้ึ ดว้ ย ตวั อยา่ งโปรแกรมท่ี 9.12 การวาง assert postconditions ไวห้ ลงั จากการเรยี กฟังชนั เพอ่ื ตรวจสอบเอา พุตทส่ี ่งกลบั Program Example 9.12: assert postconditions 1 # Assert postconditions 2 def DIV(x, y): 3 return x / y 4 result = DIV(5, 6) 5 assert result > 1, \"Result less than zero\" ห น้ า 208
Traceback (most recent call last): OUTPUT File \"C:/Python34/exam9_12.py\", line 6, in <module> assert result > 1, \"Result less than zero\" AssertionError: Result less than zero จากตวั อยา่ งโปรแกรมท่ี 9.12 ซง่ึ เหมอื นกบั โปรแกรมท่ี 9.11 แต่แตกต่างตรงทใ่ี นตวั อยา่ งน้ีทา การวาง assert ไวห้ ลงั จากทเ่ี รยี กฟังชนั DIV แลว้ (บรรทดั ท่ี 5) ผลลพั ธท์ ไ่ี ดจ้ ากฟังชนั จะถูกนามา ตรวจสอบในบรรทดั ท่ี 6 วา่ ค่าทไ่ี ดจ้ ากการคานวณตอ้ งเป็นค่าทม่ี ากกวา่ 1 เทา่ นัน้ ถา้ เป็นเทจ็ assert จะแสดงความผดิ พลาดโดยพมิ พว์ ่า “Result less than zero” ตวั อยา่ งโปรแกรมท่ี 9.13 เป็นการใช้ assert ในกรณตี ่างๆ Program Example 9.13: other assert 1 # Assert for any conditions 2 x = 0 3 assert x == 0, \"X must be 0 only\" 4 5 f = lambda x: x*x 6 assert f(2) == 4 7 assert f(3) == 9 8 9 y = 5 10 value = 0 11 if y < 5: 12 value = -1 13 elif y > 5: 14 value = 1 15 else: 16 value = 0 17 assert value == 0 จากโปรแกรมตวั อยา่ งท่ี 9.13 แสดงการใชง้ าน assert ในการตรวจสอบสมมตฐิ านในกรณตี ่างๆ โดยเรม่ิ จากบรรทดั ท่ี 3 เป็นการตรวจสอบว่าค่าในตวั แปร x ทก่ี าหนดไว้ (บรรทดั ท่ี 2) ยงั คงเป็น 0 อยู่ หรอื ไม่ เมอ่ื โปรแกรมทางานต่อไปเรอ่ื ยๆ แลว้ สมมตวิ ่ามกี ารเปลย่ี นแปลงคา่ ในตวั แปร x ใหม้ คี า่ ไม่ เทา่ กบั 0 โปรแกรมจะพมิ พข์ อ้ ความว่า “X must be 0 only” บรรทดั ท่ี 5 โปรแกรมทาการสรา้ งฟังชนั lambda ซง่ึ ทาหน้าทย่ี กกาลงั สองของ x โปรแกรมทา การวาง assert ไวด้ า้ นหน้าฟังชนั lambda (บรรทดั ท่ี 6 และ 7) เมอ่ื เรยี กใชฟ้ ังชนั lambda พรอ้ มกบั ค่าคงทเ่ี ป็นอากวิ เมนตเ์ ท่ากบั 2 ผลลพั ธท์ ไ่ี ดจ้ ะตอ้ งเป็น 4 เทา่ นนั้ (ถา้ ไมเ่ ท่ากบั 4 โปรแกรมจะแสดง ขอ้ ผดิ พลาดจาก assert) เชน่ เดยี วกบั บรรทดั ท่ี 7 เมอ่ื เรยี กฟังชนั lambda พรอ้ มกบั ค่าคงทเ่ี ป็นอากวิ เมนตเ์ ท่ากบั 3 ผลลพั ธท์ ไ่ี ดจ้ ะตอ้ งเป็น 9 เทา่ นัน้ บรรทดั ท่ี 9 โปรแกรมทาการกาหนดค่าใหต้ วั แปร y = 5 และ value = 0 เมอ่ื ตรวจสอบเงอ่ื นใน คาสงั่ if ในบรรทดั ท่ี 11 จะไดผ้ ลลพั ธเ์ ป็นเทจ็ (เพราะ y มากกวา่ 0) โปรแกรมจงึ เล่อื นมาตรวจสอบ เงอ่ื นไขต่อทค่ี าสงั่ elif ในบรรทดั ท่ี 13 จะไดผ้ ลลพั ธเ์ ป็นเทจ็ (เพราะ y เทา่ กบั 5) โปรแกรมจงึ เลอ่ื นไป ห น้ า 209
ทางานต่อทค่ี าสงั่ else ในบรรทดั ท่ี 15 โดยกาหนดค่าใหก้ บั ตวั แปร value = 0 เมอ่ื เสรจ็ จากคาสงั่ else แลว้ โปรแกรมจะตรวจสอบคา่ ใน value ดว้ ย assert โดยกาหนดไวว้ ่าคา่ ในตวั แปร value ตอ้ งเป็น 0 เท่านัน้ ถา้ value เป็นคา่ อ่นื ๆ ทไ่ี มเ่ ท่ากบั 0 assert จะแจง้ ความผดิ พลาดทนั ที ตวั อยา่ งโปรแกรมท่ี 9.14 เป็นโปรแกรมแปลงคา่ อุณหภมู จิ าก Kalvin เป็น Fahrenheit Program Example 9.14: Kalvin to Fahrenheit 1 # Convert Kelvin to Fahrenheit 2 def KelvinToFahrenheit(Temperature): 3 assert(Temperature >= 0),\"Colder than absolute zero!\" 4 return((Temperature - 273) * 1.8) + 32 5 6 print(KelvinToFahrenheit(273)) 7 print(int(KelvinToFahrenheit(505.78))) 8 print(KelvinToFahrenheit(-5)) 32.0 451 OUTPUT Traceback (most recent call last): File \"C:/Python34/exam9_14.py\", line 8, in <module> print (KelvinToFahrenheit(-5)) File \"C:/Python34/exam9_14.py\", line 3, in KelvinToFahrenheit assert (Temperature >= 0),\"Colder than absolute zero!\" AssertionError: Colder than absolute zero! จากโปรแกรมตวั อยา่ งท่ี 9.14 เป็นการแปลงอุณหภมู จิ าก Kelvin ไปเป็น Fahrenheit โดย โปรแกรมไดท้ าการตงั้ สมมตฐิ านว่าค่าของอุณหภมู ิ (Temperature) จะตอ้ งไมเ่ ป็นค่าตดิ ลบ (บรรทดั ท่ี 3) ถา้ คา่ ดงั กลา่ วทร่ี บั เขา้ มาประมวลผลในฟังชนั เป็นค่าลบ assert จะแสดงความผดิ พลาดออกมาเป็น ขอ้ ความคอื “Colder than absolute zero!” จบบทท่ี 9 ห น้ า 210
บทที่ 10 การจดั การแฟ้มข้อมลู (File Management) 1. แฟ้มข้อมลู คืออะไร? แฟ้มขอ้ มลู (File) หมายถงึ ขอ้ สนเทศหรอื ขอ้ มลู ทม่ี ขี นาดเลก็ ทส่ี ดุ ทค่ี อมพวิ เตอรส์ ามารถแสดง ใหผ้ ใู้ ชเ้ หน็ ได้ โดยจดั เกบ็ ขอ้ มลู ในลกั ษณะระเบยี น (Record) แฟ้มจะถกู จดั เกบ็ อยใู่ นหน่วยความจา ภายนอก (External storage) ชนิดถาวร เช่น ฮารด์ ดสิ ก์ แผ่นซดี ี เป็นตน้ วตั ถุประสงคใ์ นการจดั เกบ็ ขอ้ มลู จะแตกต่างกนั ตามลกั ษณะการใชง้ าน เช่น ขอ้ มลู ทใ่ี ชใ้ นสานกั งานส่วนใหญ่เป็นแฟ้มประเภท เวริ ด์ โปรเซสเซอร์ เชน่ .doc, .xls, .xml เป็นตน้ ขอ้ มลู เกย่ี วกบั มลั ตมิ เี ดยี เชน่ .wmv, .mp4, .dat หรอื .avi เป็นตน้ ขอ้ มลู ทใ่ี ชส้ าหรบั ประมวลผลเชน่ .exe, .com เป็นตน้ ซง่ึ สามารถแบ่งตามชนดิ ของ แฟ้มขอ้ มลู ไดเ้ ป็น 2 ประเภทใหญ่ๆ คอื 1) แฟ้มขอ้ ความ (Text file) สาหรบั เกบ็ ตวั อกั ษร ตวั เลข หรอื ขอ้ ความ ทส่ี ามารถอ่านทาความ เขา้ ใจได้ ตวั อยา่ งแฟ้มขอ้ มลู เช่น .txt, .doc, .ini, .xml, .c, .py เป็นตน้ 2) แฟ้มไบนาร่ี (Binary file) สาหรบั ใชเ้ กบ็ ขอ้ มลู ระบบ หรอื คาสงั่ ของคอมพวิ เตอรร์ ะดบั ล่างสุด และส่วนใหญ่ไมส่ ามารถอ่านทาความเขา้ ใจได้ ตวั อยา่ งแฟ้มขอ้ มลู ประเภทน้ี เชน่ .exe, .com, .msi, .mp3, .wmv, .dat, .zip, .class หรอื .o เป็นตน้ 2. การบริหารจดั การกบั แฟ้มข้อมลู (File Management) การจดั การกบั แฟ้มขอ้ มลู นนั้ มลี าดบั ขนั้ ตอนการทางาน 3 ขนั้ ตอน คอื 1) การเปิดแฟ้มขอ้ มลู มคี ุณสมบตั ิ 4 ประการคอื a. เปิดแฟ้มเพ่อื อ่านอยา่ งเดยี ว ใชส้ ญั ลกั ษณ์ r (read only) b. เปิดแฟ้มเพ่อื ทาการเขยี น ใชส้ ญั ลกั ษณ์ w (write) c. เปิดแฟ้มเพอ่ื ทาการอ่านและเขยี น ใชส้ ญั ลกั ษณ์ rw (read-write) d. เปิดแฟ้มเพอ่ื ปรบั ปรงุ ขอ้ มลู ใชส้ ญั ลกั ษณ์ a (append) 2) การใชง้ านหรอื ดาเนนิ การกบั แฟ้มขอ้ มลู ประกอบไปดว้ ย ห น้ า 211
a. การอ่านและเขยี นขอ้ มลู b. การลบและแกไ้ ขขอ้ มลู c. การคน้ หาและแทนทข่ี อ้ มลู d. การบบี อดั และขยายแฟ้มขอ้ มลู e. การแสดงและการกาหนดคุณสมบตั ขิ องแฟ้มขอ้ มลู (Permission) f. และอ่นื ๆ 3) การปิดแฟ้มขอ้ มลู การเปิ ดและปิ ดแฟ้ม (Opening and Closing Files) การเปิ ดแฟ้ม (Opening files) คาสงั่ เปิดแฟ้มขอ้ มลู ในไพธอนคอื คาสงั่ open ซง่ึ เป็นชนิด built-in ฟังชนั คาสงั่ จะทาการสรา้ ง ออปเจก็ ของแฟ้ม (File object) ขน้ึ มา เพ่อื ใชส้ าหรบั อา้ งองิ ในการเรยี กใชง้ านแฟ้มต่อไป รปู แบบคาสงั่ ในการเปิดแฟ้มขอ้ มลู ในไพธอน แสดงไดด้ งั น้คี อื file object = open(file_name [, access_mode][, buffering]) object คอื ออ็ ปเจก็ ของแฟ้มทถ่ี กู ใชใ้ นการอา้ งองิ ไปยงั แฟ้มจรงิ ๆ ท่เี กบ็ อยใู่ น หน่วยความจาชนิดถาวร เช่น ฮารด์ ดสิ ก์ open คอื ฟังชนั เปิดแฟ้มขอ้ มลู file_name คอื ชอ่ื ของแฟ้มขอ้ มลู ทผ่ี เู้ ขยี นโปรแกรมตอ้ งการใชง้ าน access_mode คอื วธิ กี ารเขา้ ใชง้ านแฟ้ม เช่น อ่านอยา่ งเดยี ว เขยี น หรอื ทงั้ อ่านและ เขยี น เป็นตน้ ซง่ึ จะกาหนดดว้ ยตวั อกั ษร (โหมดในการเปิดแฟ้มขอ้ มลู ) ดไู ดจ้ ากตาราง ท่ี 10.1 เมอ่ื ไมก่ าหนด access_mode ไพธอนจะถอื ว่าเป็นการเปิดแฟ้มเพอ่ื อ่านอยา่ ง เดยี ว buffering คอื หน่วยความจาชวั่ คราวเพ่อื ใชส้ าหรบั เกบ็ ขอ้ มลู ก่อนนาไปประมวลผล เน่อื งจากการอ่านเขยี นขอ้ มลู กบั หน่วยความจาถาวรจะทางานไดช้ า้ มาก ดงั นนั้ ไพธอน จาเป็นตอ้ งสรา้ งแหล่งสาหรบั พกั ขอ้ มลู เอาไวก้ ่อน เมอ่ื ขอ้ มลู เตม็ จานวนพน้ื ทท่ี ก่ี นั ไว้ เป็นบฟั เฟอรแ์ ลว้ โปรแกรมจงึ ค่อยนาเอาขอ้ มลู ดงั กล่าวไปประมวลผล ถา้ กาหนดค่า buffer เป็น 0 แสดงวา่ ไมใ่ ชห้ น่วยความจาชนิดบฟั เฟอร์ ถา้ กาหนดเป็น 1 ไพธอนจะใช้ บฟั เฟอรใ์ นการอ่านเขยี นแฟ้มแบบทลี ะบรรทดั ถา้ กาหนดเป็นเลขจานวนเตม็ ทม่ี ากกว่า 1 คอื เป็นการจองหน่วยความจาตามจานวนทร่ี ะบุไว้ แต่ถา้ ตวั เลขทก่ี าหนดเป็นค่าตดิ ห น้ า 212
ลบ ไพธอนจะใชค้ า่ ขนาดของบฟั เฟอรเ์ ท่ากบั จานวนทร่ี ะบบปฏบิ ตั ิการกาหนดไว้ (โดย ปกตจิ ะอย่ทู ป่ี ระมาณ 4 – 16 K สาหรบั วนิ โดวส)์ ตารางที่ 10.1 แสดงอกั ษร หรอื กลุ่มของตวั อกั ษรทใ่ี ชใ้ นการเปิดแฟ้มขอ้ มลู (โหมด) โหมด คาอธิบาย r เปิดแฟ้มทม่ี อี ยแู่ ลว้ เพอ่ื อ่านเพยี งอยา่ งเดยี ว ตวั ชจ้ี ะชไ้ี ปยงั ตาแหน่งเรมิ่ ตน้ ของแฟ้ม (เป็น โหมดการใชง้ านปกติ (default) ถา้ ผเู้ ขยี นโปรแกรมไมก่ าหนดโหมดในการเปิดแฟ้มไว้) rb เปิดแฟ้มชนิดไบนารเ่ี พอ่ื อ่านเพยี งอยา่ งเดยี ว ตวั ช้อี ยตู่ าแหน่งเรมิ่ ตน้ ของแฟ้ม r+ เปิดแฟ้มเพ่อื อ่านและเขยี น โดยทข่ี อ้ มลู เก่ายงั คงอยู่ ตวั ชอ้ี ยตู่ าแหน่งเรมิ่ ตน้ rb+ เปิดแฟ้มชนิดไบนารเ่ี พ่อื อ่านและเขยี น โดยทข่ี อ้ มลู เก่ายงั คงอยู่ ตวั ชอ้ี ยตู่ าแหน่งเรม่ิ ตน้ w เปิดแฟ้มเพ่อื เขยี นเท่านนั้ ในกรณที ม่ี แี ฟ้มอยแู่ ลว้ ขอ้ มลู ทอ่ี ยใู่ นแฟ้มเดมิ จะถูกเขยี นทบั ถา้ ไมม่ แี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ ตวั ชอ้ี ยตู่ าแหน่งเรม่ิ ตน้ wb เปิดแฟ้มชนดิ ไบนารเี พอ่ื เขยี นเท่านนั้ ในกรณีทม่ี แี ฟ้มอยแู่ ลว้ ขอ้ มลู ทอ่ี ยใู่ นแฟ้มเดมิ จะถกู เขยี นทบั ถา้ ไมม่ แี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ ตวั ชอ้ี ยตู่ าแหน่งเรม่ิ ตน้ w+ เปิดแฟ้มเพ่อื อ่านและเขยี น ในกรณที ม่ี แี ฟ้มอยแู่ ลว้ ขอ้ มลู ทอ่ี ยใู่ นแฟ้มเดมิ จะถกู เขยี นทบั ถา้ ไมม่ แี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ ตวั ชอ้ี ยตู่ าแหน่งเรมิ่ ตน้ wb+ เปิดแฟ้มชนดิ ไบนารเ่ี พอ่ื อ่านและเขยี น ในกรณีทม่ี แี ฟ้มอย่แู ลว้ ขอ้ มลู ทอ่ี ยใู่ นแฟ้มเดมิ จะถูก เขยี นทบั ถา้ ไม่มแี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ ตวั ชอ้ี ยตู่ าแหน่งเรม่ิ ต้น a เปิดแฟ้มเพ่อื เขยี นขอ้ มลู ต่อทา้ ยแฟ้ม ตวั ชจ้ี ะอยใู่ นตาแหน่งสุดทา้ ยในแฟ้ม ในกรณที ม่ี แี ฟ้ม อยแู่ ลว้ จะเขยี นขอ้ มลู ต่อ ถา้ ไมม่ แี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ ab เปิดแฟ้มชนิดไบนารเ่ี พอ่ื เขยี นขอ้ มลู ต่อทา้ ยแฟ้ม ตวั ชจ้ี ะอยใู่ นตาแหน่งสุดทา้ ยในแฟ้ม ใน กรณที ม่ี แี ฟ้มอย่แู ลว้ จะเขยี นขอ้ มลู ต่อ ถา้ ไมม่ แี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ a+ เปิดแฟ้มเพ่อื อ่านและเขยี น ตวั ชจ้ี ะอยตู่ าแหน่งสุดทา้ ยของขอ้ มลู ในแฟ้ม ในกรณที ม่ี แี ฟ้มอยู่ แลว้ จะเขยี นขอ้ มลู ต่อ ถา้ ไม่มแี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ ab+ เปิดแฟ้มชนดิ ไบนารเ่ี พ่อื อ่านและเขยี น ตวั ชจ้ี ะอยตู่ าแหน่งสุดทา้ ยของขอ้ มลู ในแฟ้ม ในกรณี ทม่ี แี ฟ้มอยแู่ ลว้ จะเขยี นขอ้ มลู ต่อ ถา้ ไมม่ แี ฟ้มขอ้ มลู อยู่ จะสรา้ งแฟ้มขน้ึ ใหม่ b เปิดอ่านแฟ้มขอ้ มลู โดยไมส่ นใจรหสั ปิดทา้ ย (\\n) ของแฟ้ม U เปิดอ่านแฟ้มขอ้ มลู ประเภท Unicode ซง่ึ มคี วามแตกต่างกนั ในเรอ่ื งของรหสั ปิดทา้ ยบรรทดั เช่น ถา้ เป็นแฟ้มทวั่ ๆ ไป จะใชร้ หสั ปิดทา้ ยบรรทดั เป็น \\n แต่ถา้ เป็นแฟ้มบนวนิ โดวสจ์ ะใช้ \\r แทน เป็นตน้ Note: สญั ลกั ษณ์ + ทใ่ี ชใ้ นตารางท่ี 10.1 คอื แฟ้มมคี ุณสมบตั ทิ งั้ อ่านและเขยี น ผเู้ ขยี น โปรแกรมสามารถผสมสญั ลกั ษณ์ในการเปิดแฟ้มได้ เช่น rU คอื เปิดอ่านแฟ้ม Unicode เป็น ตน้ ห น้ า 213
คณุ สมบตั ิท่ีเกี่ยวข้องกบั แฟ้มข้อมลู เมอ่ื แฟ้มขอ้ มลู ถกู เปิดใชง้ านแลว้ ผเู้ ขยี นโปรแกรมสามารถตรวจสอบคุณสมบตั ติ ่างๆ ของแฟ้ม ไดด้ งั น้ี ตรวจสอบวา่ แฟ้มขอ้ มลู ถูกปิดหรอื ยงั มรี ปู แบบคอื file.closed ฟังชนั สง่ คา่ กลบั เป็นจรงิ เมอ่ื แฟ้มถกู ปิดแลว้ ตรวจสอบว่าแฟ้มขอ้ มลู มโี หมดการเขา้ ใชง้ านอยา่ งไร file.mode ฟังชนั สง่ ค่ากลบั เป็นโหมดทเ่ี ปิดใชง้ านอยู่ ตรวจสอบช่อื ของแฟ้มขอ้ มลู file.name ฟังชนั สง่ คา่ กลบั เป็นชอ่ื ของแฟ้ม ตวั อยา่ งโปรแกรมท่ี 10.1 แสดงคณุ สมบตั ขิ องแฟ้มขอ้ มลู ทถ่ี ูกเปิดใชง้ านอยู่ Program Example 10.1: file attributes 1 # Show information about file 2 # Open a file 3 f = open(\"MyFile.txt\", \"w\") 4 print (\"Name of the file: \", f.name) 5 print (\"Closed or not : \", f.closed) 6 print (\"Opening mode : \", f.mode) Name of the file: MyFile.txt Closed or not : False OUTPUT Opening mode : w จากโปรแกรมตวั อยา่ งท่ี 10.1 เรมิ่ ตน้ บรรทดั ท่ี 3 โปรแกรมเปิดแฟ้มชอ่ื MyFile.txt ดว้ ยคาสงั่ open ในโหมดเขยี นอยา่ งเดยี ว (w) อ๊อปเจก็ ทไ่ี ดจ้ ากคาสงั่ เปิดแฟ้มเกบ็ ไวใ้ นตวั แปร f เพอ่ื ใชอ้ า้ งองิ แฟ้ม จรงิ ในหน่วยความจา บรรทดั ท่ี 4 โปรแกรมพมิ พช์ อ่ื แฟ้มโดยใชค้ าสงั่ f.name ผลลพั ธท์ ไ่ี ดค้ อื MyFile.txt บรรทดั ท่ี 5 โปรแกรมตรวจสอบแฟ้มว่าถูกปิดหรอื ไมด่ ว้ ยคาสงั่ f.closed ผลลพั ธค์ อื False (แฟ้มยงั ไม่ ถูกปิด) และบรรทดั ท่ี 6 โปรแกรมแสดงโหมดการใชง้ านแฟ้มดว้ ยคาสงั่ f.mode ผลลพั ธค์ อื w (เปิดแฟ้ม เพ่อื เขยี น) การปิ ดแฟ้ม (Closing files) หลงั จากผเู้ ขยี นโปรแกรมใชค้ าสงั่ เปิดแฟ้มและดาเนินการใดๆ กบั แฟ้มขอ้ มลู แลว้ จาเป็นตอ้ งปิด แฟ้มทุกๆ ครงั้ ทงั้ น้เี พราะขอ้ มลู ต่างๆ ทอ่ี ยใู่ นหน่วยความจาชวั่ คราวอาจจะยงั ไมถ่ ูกเขยี นกลบั ไปยงั ห น้ า 214
แฟ้มขอ้ มลู ทอ่ี ยใู่ นหน่วยความจาถาวร ดงั นนั้ คาสงั่ close (ปิดแฟ้ม) จะชว่ ยใหข้ อ้ มลู เหลา่ นนั้ ถูกบนั ทกึ ในบางครงั้ ผเู้ ขยี นโปรแกรมอาจจะลมื หรอื โปรแกรมอาจจะเกดิ ขอ้ ผดิ พลาดขน้ึ ทาใหแ้ ฟ้มทถ่ี ูกเปิดไว้ ไมไ่ ดร้ บั การปิดลง ซง่ึ สง่ ผลใหส้ น้ิ เปลอื งเน้อื ท่ขี องหน่วยความจา ไพธอนจงึ ไดเ้ ตรยี มมาตรการทช่ี ว่ ย จดั การกบั ปัญหาเหลา่ น้ีใหร้ ะดบั หน่งึ คอื เมอ่ื ผใู้ ชง้ านเปิดแฟ้มไวแ้ ต่ไมไ่ ดส้ งั่ ใหโ้ ปรแกรมทาการปิดแฟ้ม ไพธอนจะปิดแฟ้มดงั กล่าวใหเ้ องโดยอตั โนมตั ิ เมอ่ื ผใู้ ชง้ านไดท้ าการเปิดแฟ้มอ่นื ๆ ขน้ึ ใหม่ รปู แบบคาสงั่ ในการปิดแฟ้มขอ้ มลู ในไพธอนแสดงไดด้ งั น้คี อื fileObject.close() fileObject คอื ออ็ ปเจก็ ของแฟ้มทต่ี อ้ งการปิด และ close คอื เมธอดทใ่ี ชใ้ นการปิดแฟ้มขอ้ มลู สาหรบั ตวั อยา่ งปิดแฟ้มดงั โปรแกรมท่ี 10.2 ตวั อยา่ งโปรแกรมท่ี 10.2 Program Example 10.2: close file 1 # Show Opening and Closing files 2 FilePath = \"C:\\\\Python34\\\\ทดสอบอา่ นไทย.txt\" 3 try: 4 f = open(FilePath, \"rU\") 5 if f: 6 print(\"สามารถเปิดแฟ้ม :\",FilePath, \"ไดแ้ ลว้ \") 7 print (\"Name of the file: \", f.name) 8 print (\"Opening mode : \", f.mode) 9 str = f.readline() 10 print(\"ขอ้ ความในแฟ้มคอื \",str) 11 except IOError as err: 12 print(\"ไมส่ ามารถเปิดแฟ้มไดเ้ พราะ :\",err.args) 13 else: 14 print(\"ปิดแฟ้มเรยี บรอ้ ยแลว้ \") 15 f.close() แฟ้มขอ้ มลู อนิ พุตทใ่ี ชท้ ดสอบ Input File: ทดสอบอ่านไทย.txt แฟ้มน้ใี ชส้ าหรบั ทดสอบการเปิดและการปิดแฟ้ม ผลลพั ธใ์ นกรณที โ่ี ปรแกรมเปิดแฟ้มขอ้ มลู เพอ่ื อ่านได้ สามารถเปิดแฟ้ม : C:\\Python34\\ทดสอบอ่านไทย.txt ไดแ้ ลว้ OUTPUT Name of the file: C:\\Python34\\ทดสอบอ่านไทย.txt Opening mode : rU ปิดแฟ้มเรยี บรอ้ ยแลว้ ผลลพั ธใ์ นกรณที โ่ี ปรแกรมไมส่ ามารถเปิดแฟ้มขอ้ มลู เพ่อื อ่านได้ เช่น ไม่มแี ฟ้มอยใู่ นไดเรคทรอร่ี OUTPUT ไมส่ ามารถเปิดแฟ้มไดเ้ พราะ : (2, 'No such file or directory') ห น้ า 215
จากโปรแกรมตวั อยา่ งท่ี 10.2 บรรทดั ท่ี 2 เป็นการกาหนดทอ่ี ยขู่ องแฟ้มทต่ี อ้ งการใชง้ านช่อื ว่า \"ทดสอบอ่านไทย.txt\" ใหก้ บั ตวั แปร FilePath ภายในแฟ้มดงั กลา่ วมขี อ้ ความว่า “แฟ้มน้ใี ชส้ าหรบั ทดสอบการเปิดและการปิดแฟ้ม” ลาดบั ถดั ไปบรรทดั ท่ี 3 โปรแกรมดกั จบั ความผดิ พลาดทอ่ี าจจะเกดิ ขน้ึ จากการเปิดแฟ้มขอ้ มลู บรรทดั ท่ี 4 โปรแกรมเปิดแฟ้มขอ้ มลู ชนิด Unicode (แฟ้มภาษาไทย) ในโหมด อ่านไดอ้ ยา่ งเดยี ว (\"rU\") ถา้ โปรแกรมเปิดแฟ้มไมส่ าเรจ็ จะไปทางานหลงั คาสงั่ except (บรรทดั ท่ี 11) ซง่ึ จะพมิ พข์ อ้ ความรายงานความผดิ พลาดทเ่ี กดิ ขน้ึ ออกทางจอภาพคอื \"ไมส่ ามารถเปิดแฟ้มไดเ้ พราะ\" พรอ้ มกบั ความผดิ พลาดทเ่ี กดิ ขน้ึ ในตวั แปร err.args แต่ถา้ แฟ้มสามารถเปิดใชง้ านไดต้ ามปกติ โปรแกรมจะทางานทค่ี าสงั่ if (บรรทดั ท่ี 5) ซง่ึ ตรวจสอบเงอ่ื นไขว่าอ๊อปเจก็ f มคี า่ จรงิ หรอื ไม่ (ถา้ f == None หรอื 0 แสดงว่าไม่สามารถเปิดแฟ้มได)้ ถา้ เงอ่ื นไขเป็นจรงิ โปรแกรมจะทางานในบรรทดั ท่ี 6 คอื สงั่ พมิ พข์ อ้ ความว่า \"สามารถเปิดแฟ้ม : C:\\Python34\\ทดสอบอ่านไทย.txt ไดแ้ ลว้ \" บรรทดั ท่ี 7 พมิ พช์ ่อื แฟ้มเทา่ กบั \"C:\\Python34\\ทดสอบอ่าน ไทย.txt\" บรรทดั ท่ี 8 พมิ พโ์ หมดการอ่านแฟ้มเท่ากบั \"rU\" บรรทดั ท่ี 9 โปรแกรมทาการอ่านขอ้ มลู จาก แฟ้มมา 1 บรรทดั ดว้ ยคาสงั่ readline และพมิ พข์ อ้ ความทอ่ี ่านไดอ้ อกจอภาพ เมอ่ื โปรแกรมทางาน ดงั กลา่ วเสรจ็ แลว้ จะไปทางานท่บี รรทดั ท่ี 13 หลงั คาสงั่ else โดยพมิ พข์ อ้ ความวา่ “ปิดแฟ้มเรยี บรอ้ ย แลว้ ” พรอ้ มกบั ปิดแฟ้มขอ้ มลู Note: การระบุเสน้ ทาง (path) เพ่อื เปิดแฟ้มในวนิ โดวสใ์ หใ้ ชเ้ ครอ่ื งหมาย \\\\ ในการระบุทอ่ี ยู่ เชน่ filePath = \"C:\\Python34\\\\ทดสอบอ่านไทย.txt\" การดาเนินการกบั แฟ้มข้อมลู (File Operating) การอ่านแฟ้ มข้อมลู การเขยี นโปรแกรมเพ่อื อ่านขอ้ มลู ของแฟ้มออกมาแสดงผลนิยมใชเ้ มธอด read(), readline() และ readlines ซง่ึ มรี ปู แบบคาสงั่ ดงั น้ี f.read([size]) โดย f คอื ออ็ ปเจก็ ของแฟ้มขอ้ มลู จรงิ ทต่ี อ้ งการอ้างถงึ , read คอื คาสงั่ ในการอ่านแฟ้มขอ้ มลู และ [size] คอื จานวนตวั อกั ษรทต่ี อ้ งการอ่านจากแฟ้ม ถา้ กาหนดค่า size เป็นค่าลบหรอื ไมไ่ ดร้ ะบุไว้ ไพธอนจะ ตคี วามวา่ อ่านขอ้ มลู ทงั้ แฟ้ม f.readline([size]) readline อ่านขอ้ มลู จากแฟ้มครงั้ ละ 1 บรรทดั โดยอตั โนมตั ิ แต่ผเู้ ขยี นโปรแกรมสามารถกาหนดจานวน ของตวั อกั ษรทต่ี อ้ งการอ่านได้ โดยกาหนดใน size คาสงั่ readline จะอ่านแฟ้มแต่ละบรรทดั โดย ห น้ า 216
พจิ ารณาจากรหสั การขน้ึ บรรทดั ใหม่ \\n โปรแกรมจะหยุดอ่านกต็ ่อเมอ่ื พบรหสั จบแฟ้ม EOF (end of file) f.readlines([sizehint]) readlines อ่านขอ้ มลู จากบรรทดั แรกจนจบแฟ้ม ขอ้ มลู ทส่ี ่งกลบั ประกอบไปดว้ ยขอ้ มลู หลายๆ บรรทดั ถา้ กาหนดคา่ ใน sizehint คาสงั่ readline จะเปลย่ี นจากการอ่านแฟ้มทงั้ หมดเป็นการอ่านตามจานวนท่ี ระบใุ น sizehint ซง่ึ ค่าทก่ี าหนดใน sizehint จะมหี น่วยเป็นไบต์ (1 ไบตเ์ ท่ากบั 8 บติ ) Note: เมอ่ื แฟ้มไมม่ ขี อ้ มลู ใดๆ (แฟ้มวา่ ง) คาสงั่ read จะส่งกลบั ค่า null กลบั ไปใหผ้ เู้ รยี กใช้ หรอื มคี วามยาวเท่ากบั 0 แต่ถา้ เป็นบรรทดั ว่างความยาวของบรรทดั ว่างจะมคี ่าเท่ากบั 1 ตวั อยา่ งโปรแกรมท่ี 10.3 แสดงการใชค้ าสงั่ read, readline และ readlines Program Example 10.3: read, readline, readlines 1 # Testing read, readline(s) mothod 2 FilePath = \"C:\\Python34\\README.txt\" 3 try: 4 f = open(FilePath) 5 #Testing read method 6 str = f.read() 7 print(str) 8 #Testing readlines method 9 f = open(FilePath) 10 str = f.readlines(15) 11 print(str) 12 #Testing readline method 13 f = open(FilePath) 14 while 1: 15 line = f.readline() 16 if len(line): 17 print(line) 18 else: break 19 except IOError as err: 20 print(\"Cann't open file because :\",err.args) 21 else: 22 print(\"This file was closed!\") 23 f.close() ผลลพั ธข์ องการทดสอบคาสงั่ read This is Python version 3.4.0 beta 1 OUTPUT =================================== Copyright (c) 2001, 2002, 2003, 2004, 2005,… …… All trademarks referenced herein are property of their respective holders. ห น้ า 217
This file was closed! ผลลพั ธข์ องการทดสอบคาสงั่ readlines ['This is Python version 3.4.0 beta 1\\n'] This file was closed! OUTPUT ผลลพั ธข์ องการทดสอบคาสงั่ readline OUTPUT This is Python version 3.4.0 beta 1 =================================== Copyright (c) 2001, 2002, 2003, 2004, 2005,… …… All trademarks referenced herein are property of their respective holders. This file was closed! จากตวั อยา่ งโปรแกรมท่ี 10.3 แสดงตวั อยา่ งการใชง้ านคาสงั่ read, readline และ readlines เรมิ่ ตน้ ในบรรทดั ท่ี 2 โปรแกรมกาหนดทอ่ี ยขู่ องแฟ้มช่อื README.txt ใหก้ บั ตวั แปร FilePath ต่อจากนนั้ บรรทดั ท่ี 4 โปรแกรมจะทาการเปิดแฟ้มดว้ ยคาสงั่ open ซง่ึ เป็นการเปิดแฟ้มเพ่อื อ่านเท่านนั้ ออ็ ปเจก็ ทไ่ี ดจ้ ากการเปิดแฟ้มจะถกู เกบ็ ไวใ้ น f เพอ่ื ใชส้ าหรบั อา้ งองิ แฟ้ม บรรทดั ท่ี 6 โปรแกรมอ่าน ขอ้ มลู จากแฟ้มในครงั้ เดยี วดว้ ยคาสงั่ read และพมิ พข์ อ้ ความทงั้ หมดออกทางจอภาพ (บรรทดั ท่ี 7) ลาดบั ถดั ไปบรรทดั ท่ี 9 โปรแกรมทาการเปิดแฟ้มใหมด่ ว้ ยคาสงั่ open (เน่อื งจากการอ่านแฟ้ม ดว้ ยคาสงั่ read ในครงั้ แรกทาใหต้ วั ชต้ี าแหน่งของแฟ้มชไ้ี ปยงั ตาแหน่งทา้ ยแฟ้มแลว้ เมอ่ื เปิดแฟ้มใหม่ ตวั ชจ้ี ะเรมิ่ ทต่ี น้ แฟ้ม) บรรทดั ท่ี 10 โปรแกรมทาการอ่านแฟ้มดว้ ยคาสงั่ readlines ในทน่ี ้ไี ดก้ าหนด sizehint ใหม้ คี ่าเทา่ กบั 15 นนั่ คอื แฟ้มจะถูกอ่านขอ้ มลู เขา้ มา 1 บรรทดั (ถา้ สมมตวิ า่ 1 บรรทดั มี 30 ตวั อกั ษร เมอ่ื กาหนดค่า sizehint มคี ่าระหว่าง 1 - 30 ขอ้ มลู ทอ่ี ่านไดจ้ ะเทา่ กบั 1 บรรทดั ) และพมิ พ์ ขอ้ ความทงั้ หมดออกทางจอภาพ (บรรทดั ท่ี 11) ลาดบั ถดั ไปบรรทดั ท่ี 13 โปรแกรมเปิดแฟ้มใหมเ่ พ่อื ใหต้ วั ชช้ี ท้ี ต่ี าแหน่งเรมิ่ ต้นแฟ้ม บรรทดั ท่ี 14 โปรแกรมทาการอ่านขอ้ มลู ทลี ะบรรทดั ไปเรอ่ื ยๆ จนกวา่ จะหมดแฟ้มดว้ ยคาสงั่ while 1 บรรทดั ท่ี 15 โปรแกรมอ่านขอ้ มลู แบบทลี ะบรรทดั โดยใชค้ าสงั่ readline ขอ้ ความทอ่ี ่านไดน้ าไปเปรยี บเทยี บดว้ ย คาสงั่ if (บรรทดั ท่ี 16) วา่ โปรแกรมอ่านแฟ้มขอ้ มลู หมดหรอื ยงั (ถา้ ความยาวของขอ้ มลู ทอ่ี ่านไดม้ คี ่า เท่ากบั 0 แสดงว่าขอ้ มลู หมดแฟ้มแลว้ แต่ถา้ ความยาวเท่ากบั 1 แสดงวา่ เป็นบรรทดั วา่ ง) เมอ่ื ความยาว ไมเ่ ป็น 0 โปรแกรมทาการพมิ พข์ อ้ ความออกจอภาพ (บรรทดั ท่ี 17) แต่ถา้ ความยาวเป็น 0 โปรแกรมจะ หยดุ การทางานของ while ดว้ ยคาสงั่ break (บรรทดั ท่ี 18) ผลจากคาสงั่ break ทาใหโ้ ปรแกรมทางาน หลงั คาสงั่ else คอื การปิดแฟ้มขอ้ มลู (บรรทดั ท่ี 23) แต่ถา้ โปรแกรมไมส่ ามารถเปิดแฟ้มไดจ้ ะเกดิ ขอ้ ผดิ พลาดขน้ึ โดยโปรแกรมจะทางานหลงั คาสงั่ except IOError (บรรทดั ท่ี 19) ห น้ า 218
การอ่านแฟ้มข้อมลู ทีละบรรทดั ในบางกรณผี เู้ ขยี นโปรแกรมตอ้ งการอ่านแฟ้มขอ้ มลู เขา้ มาประมวลผลทลี ะบรรทดั โดยไม่ จาเป็นตอ้ งเปิดแฟ้มขอ้ มลู ดว้ ยคาสงั่ open ซง่ึ ไพธอนไดจ้ ดั เตรยี มเมธอดไวใ้ หค้ อื getline ซง่ึ อยใู่ นโมดลู linecache มรี ปู แบบคาสงั่ ใชง้ านดงั น้ี linecache.getline(file_name, line_no) โดย linecache คอื ช่อื โมดลู , getline คอื ช่อื ของเมธอดทท่ี าหน้าทอ่ี ่านแฟ้มขอ้ มลู เขา้ มาทลี ะบรรทดั , file_name คอื ช่อื แฟ้มทต่ี อ้ งการเปิดใชง้ าน และ line_no คอื จานวนบรรทดั ทต่ี อ้ งการอ่าน เมอ่ื อ่าน ขอ้ มลู แลว้ ไมจ่ าเป็นตอ้ งปิดแฟ้ม แต่ควรคนื หน่วยความจาใหก้ บั ระบบดว้ ยเมธอด clearcache() สาหรบั รปู แบบการใชง้ านแสดงในโปรแกรมท่ี 10.4 ตวั อยา่ งโปรแกรมท่ี 10.4 แสดงการใชค้ าสงั่ getline Program Example 10.4: linecache.getline 1 # read file in line by line 2 import linecache 3 FilePath = \"C:\\Python34\\README.txt\" 4 for line in range(5): 5 print(linecache.getline(FilePath, line)) 6 linecache.clearcache() This is Python version 3.4.0 beta 1 =================================== OUTPUT Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, จากตวั อยา่ งโปรแกรมท่ี 10.4 โปรแกรมเรมิ่ ตน้ ในบรรทดั ท่ี 2 โดยการ import โมดลู linecache เขา้ มาทางานในโปรแกรม จากนนั้ บรรทดั ท่ี 3 โปรแกรมกาหนดตาแหน่งทอ่ี ยขู่ องแฟ้มทต่ี อ้ งการเรยี กใช้ งานชอ่ื README.txt ขนั้ ตอนต่อไปโปรแกรมใชค้ าสงั่ for (บรรทดั ท่ี 4) เพ่อื วนอ่านแฟ้มจานวน 5 บรรทดั เขา้ มาทางานในโปรแกรม บรรทดั ท่ี 5 โปรแกรมเรยี กใชเ้ มธอด getline() เพ่อื อ่านแฟ้มขอ้ มลู ทลี ะ บรรทดั โดยมพี ารามเิ ตอร์ 2 ตวั คอื ชอ่ื แฟ้ม (FilePath) และตาแหน่งบรรทดั ทต่ี อ้ งการอ่าน (line) โปรแกรมจะอ่านแฟ้มทลี ะ 1 บรรทดั จานวน 5 บรรทดั พรอ้ มกบั พมิ พข์ อ้ มลู ในแต่ละบรรทดั ออกจอภาพ เมอ่ื เสรจ็ สน้ิ การอ่านแฟ้มแลว้ โปรแกรมจะทาการเคลยี รค์ า่ ขอ้ มลู ทอ่ี ยใู่ นหน่วยความจาโดยใชเ้ มธอด clearcache (บรรทดั ท่ี 6) การอ่านแฟ้มข้อมลู ทีละคา ห น้ า 219
ในบางกรณผี เู้ ขยี นโปรแกรมตอ้ งการอ่านขอ้ มลู จากแฟ้มทลี ะคา ผเู้ ขยี นโปรแกรมสามารถใชเ้ มธ อด split() ช่วยในการแยกคาออกจากแฟ้ม ซง่ึ แสดงตวั อยา่ งการใชง้ านดงั ในโปรแกรมท่ี 10.5 ตวั อยา่ งโปรแกรมท่ี 10.5 แสดงการใชค้ าสงั่ split Program Example 10.5: split 1 # read file in word by word 2 FilePath = \"C:\\Python34\\README.txt\" 3 wordTemp = [] 4 wordCount = 0 5 file = open(FilePath, 'r') 6 for line in file: 7 for word in line.split(): 8 wordTemp.append(word) 9 wordCount = wordCount + 1 10 print(wordTemp) 11 print(wordCount) OUTPUT ['This', 'is', 'Python', 'version', '3.4.0', 'beta', '2', '===================================', 'Copyright', '(c)', '2001,', '2002,', '2003,', '2004,', … code', 'but', 'these', 'are', 'entirely', 'optional.', 'All', 'trademarks', 'referenced', 'herein', 'are', 'property', 'of', 'their', 'respective', 'holders.'] The number of word count in this file = 973 จากโปรแกรมท่ี 10.5 เป็นตวั อยา่ งการอ่านแฟ้มแบบคาต่อคาและนามาเกบ็ ไวใ้ นตวั แปรชนดิ ลสิ ต์ โดยโปรแกรมเรม่ิ ตน้ ในบรรทดั ท่ี 2 เป็นการกาหนดชอ่ื แฟ้มขอ้ มลู ทต่ี อ้ งการอ่านช่อื README.txt บรรทดั ท่ี 3 กาหนดคา่ ตวั แปร wordTemp เป็นลสิ ตว์ ่าง ([..]) เพ่อื เกบ็ คาทอ่ี ่านไดจ้ ากแฟ้ม และบรรทดั ท่ี 4 กาหนดค่าตวั แปร wordCount เทา่ กบั 0 เพ่อื ใชใ้ นการนบั คาทอ่ี ่านไดจ้ ากแฟ้ม ขนั้ ตอนต่อไปบรรทดั ท่ี 5 โปรแกรมเปิดแฟ้มชอ่ื README.txt เพอ่ื อ่านอยา่ งเดยี ว เมอ่ื เปิดแฟ้มเสรจ็ แลว้ โดยไมม่ ขี อ้ ผดิ พลาด ใดๆ เกดิ ขน้ึ โปรแกรมจะใชค้ าสงั่ for เพอ่ื อ่านขอ้ มลู จากแฟ้มเขา้ มาทลี ะบรรทดั (บรรทดั ท่ี 6) ขอ้ มลู ท่ี อ่านไดใ้ นแต่ละบรรทดั จะถกู เกบ็ ไวใ้ นตวั แปรชอ่ื line จากนนั้ บรรทดั ท่ี 7 โปรแกรมเรยี กใชเ้ มธอดช่อื split เพ่อื แยกขอ้ มลู ในตวั แปร line ออกเป็นคาๆ เกบ็ ไวใ้ นตวั แปร word โดยทางานรว่ มกบั คาสงั่ for เมอ่ื แยกแต่ละคาในบรรทดั แลว้ คาทแ่ี ยกไดจ้ ะถูกนาไปเกบ็ ในลกั ษณะแบบต่อคาโดยใชค้ าสงั่ append (บรรทดั ท่ี 8) เกบ็ ไวใ้ นตวั แปร wordTemp พรอ้ มกบั นับจานวนคาทอ่ี ่านเขา้ มาเกบ็ ไวใ้ นตวั แปร wordCount (บรรทดั ท่ี 9) เมอ่ื โปรแกรมอ่านแฟ้มขอ้ มลู หมดแลว้ จะทาการพมิ พค์ าทงั้ หมดทเ่ี กบ็ ไวใ้ นตวั แปร wordTemp แสดงออกทางจอภาพ (บรรทดั ท่ี 10) คาสงั่ สดุ ทา้ ยจะพมิ พจ์ านวนคาทน่ี ับไดท้ งั้ หมด ออกจอภาพ (บรรทดั ท่ี 11) ห น้ า 220
ตวั ชี้ตาแหน่งในแฟ้มข้อมลู การเขยี นโปรแกรมกบั แฟ้มขอ้ มลู บางครงั้ ผเู้ ขยี นมคี วามจาเป็นตอ้ งการหาตาแหน่งของตวั ชใ้ี น แฟ้มทก่ี าลงั ทางานอยใู่ นขณะนนั้ หรอื ตอ้ งการอ่าน-เขยี นแฟ้มในตาแหน่งทผ่ี เู้ ขยี นโปรแกรมตอ้ งการระบุ เอง โดยปกตขิ ณะทท่ี าการเปิดแฟ้ม ตวั ชจ้ี ะอยทู่ ต่ี าแหน่งเรม่ิ ตน้ แฟ้ม แต่ถา้ เป็นกรณกี ารเขยี นแฟ้มเพม่ิ (append) ตาแหน่งตวั ชจ้ี ะอยทู่ ด่ี า้ นทา้ ยของแฟ้ม ไพธอนไดเ้ ตรยี มเมธอดชอ่ื tell ไวใ้ หเ้ พ่อื บอกให้ ผเู้ ขยี นโปรแกรมไดท้ ราบว่าตาแหน่งตวั ช้ี ณ ขณะปัจจุบนั อยตู่ าแหน่งไหนในแฟ้มขอ้ มลู และเมอ่ื ตอ้ งการยา้ ยตาแหน่งตวั ชไ้ี ปในตาแหน่งต่างๆ ในแฟ้มจะใชค้ าสงั่ seek ซง่ึ มรี ปู แบบคอื seek(offset[, from]) โดย seek คอื คาสงั่ ทใ่ี ชเ้ คลอ่ื นยา้ ยตาแหน่งตวั ชไ้ี ปยงั ตาแหน่งต่างๆ ในแฟ้มขอ้ มลู offet คอื จานวนขอ้ มลู ทต่ี อ้ งการเคล่อื นผา่ นไป (มหี น่วยเป็นไบต)์ และ from ใชร้ ะบุตาแหน่งอา้ งองิ เพอ่ื เคล่อื นยา้ ยไปยงั ตาแหน่งต่างๆ ในแฟ้ม ถา้ กาหนด from มคี า่ เทา่ กบั 0 หมายถงึ คาสงั่ seek จะอา้ งองิ จากจดุ เรมิ่ ตน้ ของแฟ้ม ถา้ กาหนดค่าเทา่ กบั 1 หมายถงึ ใชต้ าแหน่งปัจจุบนั ในการอา้ งองิ และกาหนดค่า เทา่ กบั 2 หมายถงึ อา้ งองิ จากดา้ นทา้ ยของแฟ้ม ดงั ตวั อยา่ งโปรแกรมท่ี 10.6 Input File: TEST.txt This is Python version 3.4.0 ตวั อยา่ งโปรแกรมท่ี 10.6 แสดงการใชค้ าสงั่ tell และ seek Program Example 10.6: tell and seek 1 # tell and seek method 2 file = open(\"TEST.txt\", \"r+\") 3 str = file.read(10); 4 print (\"Read String is : \", str) 5 # Check current position 6 position = file.tell(); 7 print (\"1.Current file position after read 1:\", position) 8 # Reposition pointer at the beginning once again 9 position = file.seek(5, 0); 10 print (\"2.Current file position after seek 1:\", position) 11 str = file.read(10); 12 print (\"Again read String is : \", str) 13 print (\"2.Current file position after read 2:\", file.tell()) 14 # Reposition pointer at the current position 15 position = file.seek(0, 1); 16 print (\"3.Current file position after seek 2:\", position) 17 str = file.read(10); 18 print (\"3.Again read String is : \", str) 19 print (\"3.Current file position after read 3: \", position) 20 # Reposition pointer at the end of file 21 position = file.seek(0, 2); 22 print (\"4.Current file position after seek 3:\", position) 23 str = file.read(10); ห น้ า 221
24 print (\"4.Again read String is : \", str) 25 26 print (\"4.Current file position after read 4: \", position) 27 # Close opend file file.close() 1.Read String is : This is Py 1.Current file position after read 1: 10 OUTPUT 2.Current file position after seek 1: 5 2.Again read String is : is Python 2.Current file position after read 2: 15 3.Current file position after seek 2: 15 3.Again read String is : version 3. 3.Current file position after read 3: 25 4.Current file position after seek 3: 28 4.Again read String is : 4.Current file position after read 4: 28 จากโปรแกรมท่ี 10.6 แสดงการใชเ้ มธอด tell และ seek บรรทดั ท่ี 2 โปรแกรมเรม่ิ ตน้ ดว้ ยการ เปิดแฟ้มชอ่ื TEST.txt เพอ่ื อ่านและเขยี นโดยทข่ี อ้ มลู เดมิ ยงั คงอยู่ ในแฟ้มดงั กล่าวมขี อ้ ความคอื “This is Python version 3.4.0” เกบ็ อยู่ ขนั้ ตอนต่อไปบรรทดั ท่ี 3 โปรแกรมทาการอ่านแฟ้มจานวน 10 ตวั อกั ษร เกบ็ ไวใ้ นตวั แปร str เมอ่ื สงั่ พมิ พข์ อ้ มลู จะไดผ้ ลลพั ธ์คอื “This is Py” (ในบรรทดั ท่ี 4) สาหรบั ตาแหน่ง ของตวั ชป้ี ัจจบุ นั จะอย่ทู ต่ี าแหน่ง 10 (อกั ษรตวั t) แสดงในรปู ท่ี 10.1 Before read After read [pointer] [pointer] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 This is P y t ho n ve r sio n 3 . 4 . 0 EOF TEST.txt รปู ท่ี 10.1 แสดงการอ่านแฟ้มดว้ ยเมธอด read(10) ลาดบั ต่อไปโปรแกรมตอ้ งการแสดงตาแหน่งของตวั ชแ้ี ฟ้มปัจจบุ นั โดยใชเ้ มธอด tell (บรรทดั ท่ี 6) ผลลพั ธข์ องตาแหน่งตวั ชป้ี ัจจบุ นั เกบ็ ไวใ้ นตวั แปร position เมอ่ื พมิ พค์ า่ ในตวั แปรดงั กลา่ ว (บรรทดั ท่ี 7) ออกมาจะไดผ้ ลลพั ธเ์ ท่ากบั 10 (ตาแหน่งของตวั อกั ษร t) ต่อจากนนั้ บรรทดั ท่ี 9 โปรแกรมใชค้ าสงั่ seek(5, 0) เพอ่ื เลอ่ื นตาแหน่งตวั ชก้ี ลบั ไปยงั ตาแหน่งเรมิ่ ตน้ ของแฟ้ม (from = 0) และนบั อกั ษรจากตน้ แฟ้มไปอกี 5 (offset = 5) ตวั อกั ษร ดงั นนั้ ทาใหต้ วั ชป้ี ัจจบุ นั จะอยตู่ าแหน่งท่ี 5 (ตวั อกั ษร i แสดงในรปู ท่ี 10.2) จากนนั้ บรรทดั ท่ี 11 โปรแกรมออกคาสงั่ ใหอ้ ่านแฟ้มขอ้ มลู ไปอกี 10 ตวั อกั ษรเกบ็ ไวใ้ น str เมอ่ื พมิ พข์ อ้ มลู ทอ่ี ยใู่ น str จะไดผ้ ลลพั ธค์ อื “is Python ” สาหรบั ตาแหน่งตวั ชป้ี ัจจบุ นั หลงั จากอ่านแฟ้มแลว้ จะอยตู่ าแหน่งท่ี 15 แสดงดงั รปู ท่ี 10.2 Reference point Before read After read [pointer] [from] [pointer] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 This is P y t ho n ve r sio n 3 . 4 . 0 EOF TEST.txt รปู ที่ 10.2 แสดงการเลอ่ื นตาแหน่งตวั ชด้ี ว้ ยเมธอด seek(5, 0) และอ่านแฟ้มดว้ ย read(10) ห น้ า 222
ลาดบั ถดั ไปบรรทดั ท่ี 15 โปรแกรมเลอ่ื นตาแหน่งตวั ชโ้ี ดยอา้ งองิ จากตาแหน่งทอ่ี ยปู่ ัจจบุ นั (from = 1) และค่าของ offset จะตอ้ งถูกกาหนดใหม้ คี ่าเทา่ กบั 0 เทา่ นัน้ (มฉิ ะนนั้ โปรแกรมจะเกดิ ผดิ พลาด) เมอ่ื โปรแกรมพมิ พค์ ่าตวั ช้ี (บรรทดั ท่ี 16) หลงั จากใชค้ าสงั่ seek(0, 1) ตาแหน่งตวั ชม้ี คี ่า เท่ากบั 15 จากนนั้ บรรทดั ท่ี 17 โปรแกรมเรมิ่ อ่านตวั อกั ษรไปอกี 10 ตวั เรมิ่ จากตาแหน่งตวั อกั ษรตวั ท่ี 15 (อกั ษร v) เกบ็ ไวใ้ นตวั แปร str เมอ่ื พมิ พค์ ่าในตวั แปรดงั กล่าว (บรรทดั ท่ี 18) ผลลพั ธท์ ไ่ี ดค้ อื “version 3.” และเมอ่ื พมิ พค์ ่าตาแหน่งตวั ชป้ี ัจจบุ นั (บรรทดั ท่ี 19) จะมคี ่าเท่ากบั 25 แสดงในรปู ท่ี 10.3 Before read After read [pointer] [pointer] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 This is P y t ho n ve r sio n 3 . 4 . 0 EOF TEST.txt Reference point [from] รปู ที่ 10.3 แสดงการเลอ่ื นตาแหน่งตวั ชด้ี ว้ ยเมธอด seek(0, 1) และอ่านแฟ้มดว้ ย read(10) ในลาดบั ถดั ไปบรรทดั ท่ี 21 โปรแกรมทาการเลอ่ื นตวั ชไ้ี ปยงั ตาแหน่งทา้ ยแฟ้มดว้ ยคาสงั่ seek(0, 2) โดยกาหนดพารามเิ ตอร์ from เทา่ กบั 2 และคา่ offset ตอ้ งเทา่ กบั 0 เทา่ นัน้ ทาใหต้ วั ชป้ี ัจจุบนั อย่ทู ่ี ตาแหน่งท่ี 28 ซง่ึ เป็นตาแหน่งสุดทา้ ยของแฟ้มขอ้ มลู ต่อจากนนั้ บรรทดั ท่ี 23 โปรแกรมทาการอ่าน ตวั อกั ษรอกี 10 ตวั โดยเรม่ิ อ่านจากตาแหน่งท่ี 28 (EOF) ซง่ึ ในกรณนี ้จี ะไมม่ ตี วั อกั ษรใหอ้ ่านแลว้ เพราะตวั ชต้ี าแหน่งอยทู่ ท่ี า้ ยแฟ้ม ผลลพั ธท์ ไ่ี ดจ้ ะพมิ พค์ ่าวา่ งออกจอภาพ (บรรทดั ท่ี 24) และตาแหน่ง ตวั ชป้ี ัจจุบนั จะอยตู่ าแหน่งท่ี 28 (บรรทดั ท่ี 25) ดงั รปู ท่ี 10.4 Before/After read [pointer] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 This is P y t ho n ve r sio n 3 . 4 . 0 EOF TEST.txt Reference point [from] รปู ท่ี 10.4 แสดงการเล่อื นตาแหน่งตวั ชด้ี ว้ ยเมธอด seek(0, 2) และอ่านแฟ้มดว้ ย read(10) การเขียนแฟ้ มข้อมลู การเขยี นหรอื การปรบั ปรงุ ขอ้ มลู ในแฟ้มสาหรบั ภาษาไพธอนนยิ มใชเ้ มธอด write() และ writelines() สาหรบั คาสงั่ print>> ไพธอน 3 ไดย้ กเลกิ ไปแลว้ มรี ปู แบบคาสงั่ ดงั น้ี f.write(string) โดย f คอื ออ็ ปเจก็ ของแฟ้มขอ้ มลู จรงิ ทต่ี อ้ งการอา้ งถงึ , write คอื คาสงั่ ในการเขยี นแฟ้มขอ้ มลู และ string คอื ขอ้ ความทต่ี อ้ งการเขยี นลงแฟ้ม f.writelines(sequence) ห น้ า 223
โดย f คอื ออ็ ปเจก็ ของแฟ้มขอ้ มลู จรงิ ทต่ี อ้ งการอ้างถงึ , writelines คอื คาสงั่ ในการเขยี นแฟ้มขอ้ มลู และ sequence คอื ชุดของขอ้ ความทต่ี อ้ งการเขยี นลงแฟ้ม สาหรบั ตวั อยา่ งการเขยี นแฟ้มขอ้ มลู แสดงดงั ตวั อยา่ งโปรแกรมท่ี 10.7 ตวั อยา่ งโปรแกรมท่ี 10.7 แสดงการใชค้ าสงั่ write และ writelines Program Example 10.7: write vs writelines 1 # write, writelines 2 string1 = \"hello world in the new file\\n\" 3 string2 = \"and another line\\n\" 4 sequence = [\"Sequence string line 1\\n\", \"Sequence string line 2\"] 5 file = open(\"newfile.txt\", \"w\") 6 file.write(string1) 7 file.write(string2) 8 file.writelines(sequence) 9 file.close() OUTPUT: myfile.txt OUTPUT hello world in the new file and another line Sequence string line 1 Sequence string line 2 จากตวั อยา่ งโปรแกรมท่ี 10.7 บรรทดั ท่ี 2 โปรแกรมทาการกาหนดขอ้ ความใหก้ บั string1 เท่ากบั “hello world in the new file\\n”, string2 เท่ากบั “and another line\\n” (บรรทดั ท่ี 2) และรายการ ของขอ้ ความไวใ้ น sequence เท่ากบั [\"Sequence string line 1\\n\", \"Sequence string line 2\"] (บรรทดั ท่ี 3) ลาดบั ถดั ไปบรรทดั ท่ี 5 โปรแกรมทาการเปิดแฟ้มชอ่ื myfile.txt ในโหมดเขยี นทบั (w) และสงั่ ใหท้ า การเขยี นแฟ้มดว้ ยคาสงั่ write (บรรทดั ท่ี 6) กบั string1 และ string2 (บรรทดั ท่ี 7) สาหรบั คาสงั่ writelines จะใชเ้ ขยี นขอ้ มลู กบั คา่ ทอ่ี ยู่ตวั แปร sequence (บรรทดั ท่ี 8) เมอ่ื เปิดแฟ้มชอ่ื myfile.txt ในไดเรคทรอรป่ี ัจจุบนั จะปรากฎขอ้ ความดงั แสดงในตวั อยา่ งเอาตพ์ ตุ ขา้ งบน การใช้คาสงั่ with กบั แฟ้มข้อมลู ไพธอนไดเ้ สนอคาสงั่ ทใ่ี ชส้ าหรบั เปิดแฟ้มเพมิ่ เตมิ ใหก้ บั ผเู้ ขยี นโปรแกรม คอื คาสงั่ with ซง่ึ คาสงั่ ดงั กลา่ วเป็นคาสงั่ ทใ่ี ชง้ านคอ่ นขา้ งงา่ ย มคี วามสามารถในการปิดแฟ้ม (ไมต่ อ้ งใชค้ าสงั่ close) และ เคลยี รข์ อ้ มลู ทอ่ี ยใู่ นหน่วยความจาแบบอตั โนมตั ิ ซง่ึ มรี ปู แบบคาสงั่ คอื with open(filename) as file ห น้ า 224
โดย filename คอื ชอ่ื แฟ้มทต่ี อ้ งการเปิดใชง้ าน, file คอื อ๊อปเจก็ ทอ่ี า้ งองิ ไปยงั filename เพ่อื นาไปใชง้ าน ตวั อยา่ งการเปิดแฟ้มดว้ ยคาสงั่ with แสดงในโปรแกรมท่ี 10.8 ตวั อยา่ งโปรแกรมท่ี 10.8 แสดงการใชค้ าสงั่ with Program Example 10.8: with 1 # with with open file 2 # use with to read file 3 with open(\"newfile.txt\") as file 4 for line in file: 5 print (line) 6 7 #use with to write file 8 with open(\"hello.txt\", \"w\") as file: 9 file.write(\"Hello World\") OUTPUT hello world in the new file and another line Sequence string line 1 Sequence string line 2 OUTPUT: hello.txt OUTPUT Hello World โปรแกรมท่ี 10.8 เป็นการใชค้ าสงั่ with ในการอ่านและเขยี นแฟ้มขอ้ มลู บรรทดั ท่ี 3 โปรแกรม จะใชค้ าสงั่ with ทาการสรา้ งอ๊อปเจก็ ทอ่ี า้ งองิ ไปยงั แฟ้มขอ้ มลู ในหน่วยความจาถาวรช่อื newfile.txt โดย ใชช้ ่อื สาหรบั อา้ งองิ ชอ่ื file บรรทดั ท่ี 4 โปรแกรมใชค้ าสงั่ for เพอ่ื อ่านขอ้ มลู ทอ่ี า้ งดว้ ยอ๊อปเจก็ file ไปใช้ งานครงั้ ละ 1 บรรทดั เกบ็ ไวใ้ นตวั แปร line จากนนั้ บรรทดั ท่ี 5 โปรแกรมทาการพมิ พข์ อ้ มลู ทอ่ี ยใู่ นตวั แปร line ออกจอภาพ โปรแกรมจะทางานไปเรอ่ื ยๆ จนกว่าขอ้ มลู จะหมดแฟ้ม ลาดบั ถดั ไปบรรทดั ท่ี 8 โปรแกรมจะทาการเปิดแฟ้มชอ่ื hello.txt ในโหมดการเขยี น บรรทดั ท่ี 9 โปรแกรมทาการเขยี นขอ้ ความวา่ “Hello World” ลงไปในแฟ้มดงั กล่าว เมอ่ื เปิดแฟ้ม hello.txt ทอ่ี ยใู่ น ไดเรคทรอรป่ี ัจจบุ นั จะปรากฎผลลพั ธใ์ นตวั อยา่ งเอาตพ์ ตุ ดา้ นบน สงั เกตวา่ การใชค้ าสงั่ with ไม่ จาเป็นตอ้ งทาการปิดแฟ้มเหมอื นการใชค้ าสงั่ open โดยไมม่ คี าสงั่ with กากบั การจดั การแฟ้มและไดเรคทรอรี่ ภายในโมดลู os ของไพธอน มฟี ังชนั และเมธอดสาหรบั บรหิ ารจดั การเกย่ี วกบั การประมวลผล แฟ้มขอ้ มลู (file processing) ไวอ้ ยา่ งมากมาย เมอ่ื ตอ้ งการนามาใชง้ าน อนั ดบั แรกจะตอ้ งทาการ import เขา้ มาในโปรแกรมเสยี ก่อน ลาดบั ต่อไปจงึ เรยี กใชง้ านฟังชนั เหลา่ นนั้ ได้ ห น้ า 225
การเปลี่ยนชื่อแฟ้มข้อมลู มรี ปู แบบคาสงั่ คอื os.rename(\"current_finename\", \"new_filename\") โดย current_finename คอื ช่อื แฟ้มปัจจุบนั ทต่ี อ้ งการเปลย่ี นชอ่ื และ new_filename คอื ชอ่ื แฟ้ม ใหม่ การลบแฟ้มข้อมลู มรี ปู แบบคาสงั่ คอื os.remove(\"finename\") โดย finename คอื ช่อื แฟ้มปัจจบุ นั ทต่ี อ้ งการลบทง้ิ การสร้างไดเรคทรอรี่ มรี ปู แบบคาสงั่ คอื os.mkdir(\"dirname\") โดย dirname คอื ช่อื ไดเรคทรอรท่ี ต่ี อ้ งการสรา้ งขน้ึ ใหม่ การเปล่ียนที่อย่ขู องไดเรคทรอร่ี มรี ปู แบบคาสงั่ คอื os.chdir(\"newname\") โดย newname คอื ชอ่ื ไดเรคทรอรท่ี ต่ี อ้ งการยา้ ยเขา้ ไปทางาน การแสดงไดเรคทรอรี่ปัจจบุ นั มรี ปู แบบคาสงั่ คอื os.getcwd() เมธอดน้ไี มจ่ าเป็นตอ้ งใชพ้ ารามเิ ตอร์ การลบไดเรคทรอร่ี มรี ปู แบบคาสงั่ คอื os.rmdir(\"dirname\") โดย dirname คอื ช่อื ไดเรคทรอรท่ี ต่ี อ้ งการลบทง้ิ สาหรบั ตวั อยา่ งการจดั การแฟ้มและไดเรคทรอร่ี แสดงในโปรแกรมท่ี 10.9 ตวั อยา่ งโปรแกรมท่ี 10.9 ตวั อยา่ งการจดั การแฟ้มและไดเรคทรอร่ี Program Example 10.9: file & directory management 1 # file and directory management 2 import os 3 # Rename a file from test1.txt to test2.txt 4 os.rename(\"test1.txt\", \"test2.txt\") 5 # Delete file test2.txt 6 os.remove(\"test2.txt\") 7 # Create a directory \"C:\\\\test\" 8 os.mkdir(\"C:\\\\test1\") 9 # Changing a directory to \"C:\\\\test1\" 10 os.chdir(\"C:\\\\test1\") 11 # This would give location of the current directory 12 print(\"Current directory is:\",os.getcwd()) ห น้ า 226
13 # This would remove \"C:\\\\test1\" directory. 14 os.rmdir(\"C:\\\\test1\") Current directory is: C:\\test1 OUTPUT สาหรบั การใชง้ านฟังชนั และเมธอดเกย่ี วกบั การจดั การแฟ้มและไดเรคทรอรเ่ี พมิ่ เตมิ สามารถ อ่านไดใ้ นภาคท่ี 5 เรอ่ื ง Standard Library of Python จบบทท่ี 10 ห น้ า 227
(Super Class) (Data hinding) # Object-oriented Programming Example Comment class Car: __brand = 'No brand' color = 'No color' Class variable speed = 0 wheel = 4 seat = 4 constructor register_number = 0 def __init__(self, color='white', *args): (Variable-length arguments) self.color = color if (len(args) != 0): self.__brand = args[0] self.speed = args[1] self.wheel = args[2] self.seat = args[3] else: print(\"No argument for overriding\") Car.register_number += 1 Class variable def getBrand(self): return self.__brand def setBrand(self, brand): Encapsulation self.__brand = brand def display(self): print(\"The details of (%s) car are: color(%s) speed(%d) wheel(%d) seat(%d) reg(%d)\"%(self.__brand,self.color,self.speed,self.wheel,self.seat,self.regi ster_number)) deconstructor def __del__(self): class_name = self.__class__.__name__ (Super Class) print(class_name, \"object has destroyed\") class Accessory: radio = 'yes' mobile = 'option' aircondition = 'yes' def setAccessory(self, radio, mobile, aircon): self.radio = radio self.mobile = mobile self.aircondition = aircon def displayAccessory(self, brand): print(\"The accessories of (%s) are: radio(%s) mobile(%s) (Child class) aircon(%s)\"%(brand,self.radio,self.mobile,self.aircondition)) class ModernCar(Car, Accessory): def setBrand(self, brand): Car (Inheritance) self.__brand = brand Accessory car1 = ModernCar('blue','Toyota',150,4,4) Constructor car1.display() Deconstructor car1.setAccessory('yes','no','yes') : car1.displayAccessory(car1.getBrand()) car1._Car__brand = 'Honda' car1.displayAccessory(car1.getBrand()) del car1 ภ ภษ ห น้ า 228
11 (Object-Oriented Programming: OOP) Object Car 1 extend Car ClassProperties Object Car 7 Methods Properties extend Properties Methods Methods Properties Object Car 2 extend extend extend Methods Properties Properties Object Car 6 Methods Object Car 3 Properties Methods Properties Methods Object Car 4 Object Car 5 Methods 1. (Programming Paradigms) แนวความคดิ ในการเขยี นโปรแกรม คอื วธิ กี ารพน้ื ฐานของการเขยี นโปรแกรมคอมพวิ เตอร์ ซง่ึ สามารถจาแนกไดเ้ ป็น 4 ประเภทหลกั ๆ ไดแ้ ก่ การเขยี นโปรแกรมเชงิ ฟังกช์ นั (Functional programming) หรอื เชงิ โครงสรา้ ง (Structure programming) หรอื แบบกระบวนการ (Procedure programming) การเขยี นโปรแกรมเชงิ คาสงั่ (Imperative programming) การเขยี นโปรแกรมเชงิ วตั ถุ (Object-Oriented Programming) การเขยี นโปรแกรมเชงิ ตรรกะ (Logic programming) นอกจากรปู แบบหลกั ทงั้ 4 แลว้ ยงั มอี กี รปู แบบหน่งึ ซง่ึ ขยายความสามารถของโมดลู โปรแกรม โดยใชว้ ธิ กี ารตดั แทรกโปรแกรม เรยี กวา่ การโปรแกรมเชงิ หน่วยยอ่ ย (Aspect-Oriented programming) ในบทเรยี นก่อนๆ ทผ่ี ่านมาของหนงั สอื เล่มน้ี เป็นการกล่าวถงึ การเขยี นโปรแกรมเชงิ ฟังชนั เกอื บทงั้ หมด แต่มแี ทรกเกย่ี วกบั การเขยี นโปรแกรมเชงิ วตั ถุไวบ้ า้ ง เชน่ การเรยี กใชง้ าน Attribute เมธอด หรอื การใชง้ านคลาส เป็นตน้ สาหรบั ในบทน้ีจะเจาะลกึ สาหรบั การเขยี นโปรแกรมเชงิ วตั ถุดว้ ย ภาษาไพธอน 2. (Object-Oriented Programming Concept: OOP) ก่อนจะเขา้ ส่เู น้อื หาการเขยี นโปรแกรมเชงิ วตั ถุ จาเป็นตอ้ งกลา่ วถงึ การเขยี นโปรแกรมในรปู แบบเดมิ ๆ ก่อนว่าทาไมการเขยี นโปรแกรมแบบเก่าจงึ เรมิ่ ถูกแทนทด่ี ว้ ยแนวคดิ แบบเชงิ วตั ถุ การเขยี น ห น้ า 229
โปรแกรมในรปู แบบเดมิ มจี ุดบกพรอ่ งอยา่ งไร และแบบใหมส่ ามารถแกไ้ ขจดุ บกพรอ่ งเหลา่ นนั้ ได้จรงิ หรอื ไม่ ลองมาสารวจความแตกต่างระหวา่ งการเขยี นโปรแกรมทงั้ 2 แบบกนั ก่อน ฟ (Functional/Structure/Procedure programming) จดั เป็นการเขยี นโปรแกรมในรปู แบบเก่า มลี กั ษณะการเขยี นโปรแกรม คอื การมองปัญหาหน่งึ ๆ ออกเป็นสว่ นยอ่ ยๆ แลว้ จงึ คอ่ ยแกไ้ ขไปทลี ะส่วนจนกว่าจะไดผ้ ลลพั ธท์ ต่ี อ้ งการ ซง่ึ ประยกุ ตม์ าจากวธิ คี ดิ ของมนุษยน์ นั่ เอง เชน่ เมอ่ื ตอ้ งการแกป้ ัญหาโจทยค์ ณติ ศาสตรเ์ รอ่ื งสมการเชงิ เสน้ Ax + By = C ถา้ มนุษยค์ ดิ โดยปราศจากเคร่อื งคานวณ จะแยกคานวณประโยคคณติ ศาสตรน์ ้ที ลี ะส่วน โดยเรมิ่ ตน้ จาก นา คา่ คงท่ี A คณู กบั ค่าในตวั แปร x เมอ่ื ไดค้ าตอบแลว้ ทดไวใ้ นกระดาษก่อน ขนั้ ต่อไปคานวณ B คณู y คาตอบทไ่ี ดจ้ ะนาไปรวมกบั A คณู x ผลรวมทไ่ี ดจ้ ะถูกนาไปเปรยี บเทยี บกบั คา่ คงท่ี C ในลาดบั สดุ ทา้ ย สงั เกตวา่ ปัญหาถูกแยกและทางานเป็น 4 ขนั้ ตอน คอื 1) A คณู กบั x ผลลพั ธท์ ไ่ี ด้ พกั ไวใ้ นกระดาษทด 2) B คณู กบั y ผลลพั ธท์ ไ่ี ด้ พกั ไวใ้ นกระดาษทด 3) Ax + By ผลลพั ธท์ ไ่ี ด้ พกั ไวใ้ นกระดาษทด 4) เปรยี บเทยี บค่า Ax + By กบั C ผลลพั ธท์ ไ่ี ด้ เป็นจรงิ ยตุ กิ ารทางาน ถา้ เป็นเทจ็ กลบั ไปแกไ้ ข ถา้ ตอ้ งการหาคาตอบจากสมการเชงิ เสน้ ทม่ี รี ปู แบบ Ax + By = C จะตอ้ งทาขนั้ ตอนในลกั ษณะ ดงั กล่าวน้เี สมอๆ จงึ เรยี กว่า งานแบบฟังชนั (Function) หรอื แบบกระบวนการ (Procedure) นนั่ เอง สาหรบั มุมมองในการพฒั นาโปรแกรม คาสงั่ จะเรยี งต่อกนั ไปเรอ่ื ยๆ ทลี ะบรรทดั โปรแกรมจะเรมิ่ ทางาน จากคาสงั่ แรกสุดเรอ่ื ยไปจนถงึ คาสงั่ ทา้ ยสดุ เป็นอนั จบโปรแกรม อาจมกี ารสรา้ งเป็นโปรแกรมยอ่ ยๆ ใน โปรแกรมใหญ่บา้ งเพ่อื ลดคาสงั่ ทซ่ี ้าซอ้ นลง ? ขนาดของโปรแกรม (จานวนบรรทดั ของโปรแกรม หรอื lines of code) จะขน้ึ อยกู่ บั ความซบั ซอ้ นของปัญหา ถา้ โปรแกรมมขี นาดและความซบั ซอ้ นไมม่ ากจะไมก่ ่อใหเ้ กดิ ปัญหาและไมย่ งุ่ ยากในการทจ่ี ะพฒั นาโปรแกรมดว้ ยวธิ นี ้ี ในทางตรงกนั ขา้ ม ถา้ ปัญหามขี นาดใหญ่และ ซบั ซอ้ นมากๆ จะทาใหก้ ารเขยี นโปรแกรมซบั ซอ้ นตามไปดว้ ย และยงั พบปัญหาในเรอ่ื งของการนา โปรแกรมทเ่ี ขยี นแลว้ กลบั มาใชใ้ หม่ (Reusable) การแกไ้ ข (Modifying) การขยายเพม่ิ เตมิ (Extensible) การบารงุ รกั ษา (Maintenance) ในระยะยาวอกี ดว้ ย (Object) คอื แนวคดิ การพฒั นาโปรแกรมรปู แบบใหมท่ น่ี ามาใชก้ นั ในปัจจบุ นั เพอ่ื แกป้ ัญหาดงั กลา่ วมาแลว้ ขา้ งตน้ กบั การการเขยี นโปรแกรมแบบเชงิ ฟังชนั ถงึ แมร้ ปู แบบการเขยี นจะ ค่อนขา้ งยากและมคี วามซบั ซอ้ น แต่จะส่งผลดตี ่อการดูแลรกั ษาโปรแกรมในระยะยาว ซง่ึ แนวคดิ น้ีจะ ห น้ า 230
Search
Read the Text Version
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 1 - 50
- 51 - 100
- 101 - 150
- 151 - 200
- 201 - 250
- 251 - 300
- 301 - 350
- 351 - 400
- 401 - 450
- 451 - 500
- 501 - 550
- 551 - 600
- 601 - 650
- 651 - 661
Pages: