Tuesday, November 30, 2010

Python Programing

ทำงานกับไฟล์ด้วย Python

ประพัฒน์ สุริยผล


หลังจากที่เราผ่านการเขียนโปรแกรมกันมาเป็นปีแล้ว ผมเชื่อว่าผู้อ่านทุกท่านมีพื้นฐานการเขียนโปรแกรมที่แน่นแล้ว ถ้าเราย้อนกลับไปดูจะเห็นว่า โปรแกรมทั่วไปมีลักษณะการทำงานหลักอยู่ไม่กี่อย่าง ได้แก่ ทำตามลำดับ ทำตามเงื่อนไข และวนลูป เท่านั้นเองครับ โปรแกรมจะทำงานตามที่เราต้องการได้หรือไม่ ก็ขึ้นอยู่กับเราที่จะจัดการกับลำดับเหล่านั้นให้ถูก และเพื่อให้การทำงานของเราง่ายขึ้น เราสามารถแบ่งภาระงานของโปรแกรมออกมาเป็นส่วนย่อยๆ ที่เราได้ลองเล่นกันมาแล้วในเรื่องของ subroutine คงพอจะจำได้นะครับ


สิ่งสำคัญอีกประการหนึ่งที่จะช่วยให้เราเขียน Python ได้อย่างมีประสิทธิภาพมากขึ้น ก็คือการที่เรารู้จัก library หรือ tools ที่ Python ให้เราเรียกใช้ได้ คงพอจะจำเรื่อง reverse complement สาย DNA ที่เราเพิ่งเขียนกันมาได้ไหมครับ ตอนแรกสุด เราเขียนทุกอย่างเองหมดเลย ซึ่งก็ทำงานได้ แต่ว่าต้องเขียนกันยืดยาว แต่ถ้าหากเรารู้ว่า Python มีอะไรไว้ให้เราแล้ว เราก็สามารถเขียนได้สั้นลงมาก ดังเช่นที่เราทำกันในตอนสุดท้าย


ยังมี feature หลักอีกอย่างหนึ่งของ Python ที่ผมยังขออนุญาตค้างไว้ก่อน คือเรื่อง Object-oriented Programming (OOP) ในช่วงนี้ ผมคิดว่า ผมจะเริ่มพูดถึง feature หรือ module ต่างๆ ของ Python ที่จะทำให้เราทำงานต่างๆ ได้สะดวกขึ้นครับ


ครั้งนี้ เราจะพูดถึงการทำงานกับไฟล์ด้วย Python กัน ที่ผ่านมา เรารับค่า input ต่างๆ จากผู้ใช้ทางคีย์บอร์ด แต่การทำงาน bioinformatics ส่วนใหญ่แล้ว เรามักจะทำงานกับไฟล์ทั้งเล็กและใหญ่ และอาจจะมีจำนวนมาก ความรู้ในการทำงานกับไฟล์ด้วย Python จึงเป็นความรู้ส่วนต้นๆ ที่เราควรจะได้เรียนรู้กันครับ


Open file


เราสามารถเปิดไฟล์ขึ้นมาเพื่อเขียนหรืออ่านได้ด้วยคำสั่ง open โดยมีลักษณะการใช้งานคือ

open(filename, mode)

โดยคำสั่ง open จะคืนค่าตัวแทนของไฟล์ที่เราเปิดกลับมาให้เราเรียกใช้งาน คำสั่งนี้ต้องการพารามิเตอร์ชื่อไฟล์ที่เราต้องการเปิด ส่วน mode นั้น optional เราจะใส่หรือไม่ใส่ก็ได้ ถ้าหากเราไม่ใส่ จะถือว่าเราต้องการเปิดไฟล์เพื่อการอ่านครับ


mode ที่เป็นไปได้


mode คำอธิบาย

r อ่านไฟล์

w เขียนไฟล์ (ถ้าไฟล์เดิมมีอยู่ ให้ลบข้อมูลเดิมแล้วเขียนใหม่)

a เขียนไฟล์แบบต่อท้าย (ถ้ามีไฟล์เดิมอยู่ก่อนแล้วจะไม่ลบข้อมูลเดิม แต่เขียนต่อท้ายไฟล์เดิม)

r+ อ่านและเขียนไฟล์


โดยทั่วไป mode เหล่านี้คือ mode ที่เราจะใช้งานกัน เพราะไฟล์ส่วนใหญ่ที่เราใช้งานกันทาง bioinformatics มักจะเป็น text file หรือไฟล์ตัวหนังสือ และในระบบ linux การทำงานกับไฟล์ที่ไม่ใช่ตัวหนังสือ ก็สามารถใช้ mode เหล่านี้ได้เช่นกัน


แต่หากเราทำงานบนระบบ Windows จะมี mode เพิ่มขึ้นมาอีกอย่างหนึ่งคือ binary สำหรับเปิดไฟล์ที่ไม่ใช่ไฟล์ตัวหนังสือ Python ต้องการ mode นี้เพิ่มพิเศษ เพราะว่าต้องมีการจัดการกับการขึ้นบรรทัดใหม่ของตัวอักษรบนระบบ Windows เพราะฉะนั้น ถ้าหากเราต้องการอ่านหรือเขียนไฟล์ที่ไม่ใช่ text file เช่นไฟล์รูปภาฟ ให้เราใช้ mode เหล่านี้


mode คำอธิบาย

rb อ่านไฟล์ binary

wb เขียนไฟล์ binary (ถ้าไฟล์เดิมมีอยู่ ให้ลบข้อมูลเดิม แล้วเขียนใหม่)

ab เขียนไฟล์ binary แบบต่อท้าย

r+b อ่านและเขียนไฟล์ binary


อันที่จริง เราสามารถใช้ mode rb ในระบบ linux ได้ โดยที่ python บน linux ก็จะไม่สนใจตัว b และทำงานเหมือน mode r ปกติ


ผมจึงมีข้อแนะนำว่า ถ้าหากต้องการให้ code python ของเราทำงานได้ทั้งบน windows และ linux เมื่อเราต้องการทำงานกับ binary file ให้เราใช้ mode ที่มีตัว b อยู่ได้เลย โปรแกรมนั้นจะทำงานได้บนทุก platform


ตัวอย่างคำสั่งในการเปิดไฟล์

>>> f = open('/tmp/testfile.txt')

เปิดไฟล์ /tmp/testfile.txt เพื่ออ่าน

>>> f = open('/tmp/testfile.txt','w')

เปิดไฟล์ /tmp/testfile.txt เพื่อเขียน ถ้ามีไฟล์นี้อยู่ ให้ลบข้อมูลเก่าทิ้ง ถ้าไม่มี ให้สร้างใหม่

>>> f = open('/tmp/testfile.txt','a')

เปิดไฟล์ /tmp/testfile.txt เพื่อเขียน ถ้ามีไฟล์นี้อยู่ ให้เขียนต่อไปเลย ถ้าไม่มี ให้สร้างใหม่


Close file


โดยทั่วไป Python จะปิดไฟล์ให้เราเองโดยอัตโนมัติ เมื่อโปรแกรมจบการทำงาน แต่อาจจะมีบางครั้งที่เราต้องการปิดไฟล์ก่อนที่โปรแกรมจะทำงานเสร็จ เช่น เราต้องการความมั่นใจว่า ข้อมูลที่เราเพิ่งเขียนไปนั้น ถูกเขียนไปเรียบร้อยจริง และถ้าหากเราเปิดไฟล์นั้นขึ้นมาอ่าน ก็จะได้ข้อมูลครบทั้งหมด


ถ้าหากเราต้องการปิดไฟล์ เราสามารถใช้ method close ของ file object ที่เราได้มาจากการ open ได้ ดังตัวอย่าง


>>> f = open('/tmp/testfile.txt','w')

>>> f.close()

คุยกันเล็กน้อยเรื่อง object


รายละเอียดเรื่อง object-oriented programming จะมีเยอะครับ ผมขอยกยอดไปดังที่ได้กล่าวมาแล้ว แต่เมื่อเราใช้คำสั่ง open ผมหลีกเลี่ยงไม่พูดถึง object เลย ก็คงไม่ได้ เพราะคำสั่ง open จะคืนตัวแทนไฟล์ หรือ file object กลับมาให้เรา file object ก็จะเป็นตัวแทนของไฟล์นั้น ที่เราสามารถสั่งให้ทำอะไรก็ได้ตามที่เราต้องการ คำสั่งที่เราสามารถสั่งให้ object ทำงานนั้น เรียกว่า method

โดยปกติ ถ้าเราต้องการปิดไฟล์ ถ้าหากเราเรียกใช้งานแบบ function จะได้เป็น

>>> close(f)


ถ้าหากเราเขียนแบบนี้ แสดงว่า close เป็นฟังก์ชันทั่วไป ที่ต้องการพารามิเตอร์คือ file object เพื่อใช้ปิดไฟล์ แต่ python ไม่มีฟังก์ชันนี้ครับ มีแต่ฟังก์ชัน open


หลังจากที่เราใช้ฟังก์ชัน open แล้ว เราจะได้ file object ออกมา และเป็นหน้าที่ของเราที่จะใช้ method ของ file object เพื่อให้ทำงานตามที่เราต้องการ


เพราะฉะนั้น ถ้าหากเราต้องการปิดไฟล์ เราจะใช้เป็น


>>> f.close()


ขอให้สังเกตความแตกต่างในการเรียกครับ เราจะเรียก method ของ object ตัวไหน ก็เริ่มต้นด้วย ตัวแปร object ตามด้วยจุดและชื่อของ method ครับ และในกรณีนี้ เราไม่ได้ส่งค่าพารามิเตอร์อะไรไปให้ method close เลย เพราะว่าเราเจาะจงเรียก method close ของ file object 'f' อยู่แล้ว ซึ่ง Python แปลความหมายได้ชัดเจนว่า เราต้องการปิดไฟล์ f


ดูตัวอย่างกันอีกสักนิดครับ เพื่อให้คุ้นเคย

>>> f1 = open('/tmp/testfile.txt','w')

>>> f2 = open('/tmp/testfile2.txt','w')

>>> f1.close()

>>> f2.close()

ตัวอย่างนี้ เราเปิดไฟล์ 2 ไฟล์ ได้ file object มา 2 อัน อยู่ใน f1 และ f2 จากนั้น เราสามารถสั่งปิดไฟล์แต่ละไฟล์ได้ตามต้องการ ดังตัวอย่าง


เขียนไฟล์


เมื่อเราเข้าใจเรื่อง method แล้ว file object มี method สำหรับการเขียนไฟล์ ชื่อ write เพราะฉะนั้น เราสามารถเขียนไฟล์ได้ ดังตัวอย่าง


>>> f = open('/tmp/testfile.txt','w')

>>> f.write('hello world\n')

>>> f.close()

จะเห็นว่าเราเรียก method write ของ f และส่งข้อความ 'hello world\n' เป็นพารามิเตอร์ไป เราไม่ต้องบอกว่า เราต้องการเขียนไปที่ไฟล์ไหน ในพารามิเตอร์ เพราะว่าเราเรียก method ของ file object อยู่แล้ว ข้อความดังกล่าวจะถูกเขียนไปที่ไฟล์ /tmp/testfile.txt นั่นเอง


Method write ไม่ได้เติมตัวขึ้นบรรทัดใหม่เมื่อสิ้นสุดข้อความให้เราโดยอัตโนมัติ เพราะบางครั้งเราอาจจะไม่ต้องการก็ได้ เราจึงต้องใส่ตัวขึ้นบรรทัดใหม่เอง โดยใช้ escape character เพราะเราไม่สามารถพิมพ์ตัวขึ้นบรรทัดใหม่ลงไปได้โดยตรง (\n => new line character)


มี method สำหรับการเขียนไฟล์อีกหนึ่ง method คือ writelines ใช้สำหรับเขียนข้อมูลจาก sequence เช่น list ลงไปในไฟล์ทีเดียว เช่น

>>> data = ['1. once upon a time\n', '2. there was a lion living in a forest\n', '3. the end.\n']

>>> f = open('/tmp/testfile.txt','w')

>>> f.writelines(data)

>>> f.close()

ไฟล์ที่เขียนขึ้น สามารถเปิดอ่านได้ด้วย โปรแกรม text editor อะไรก็ได้ครับ ครั้งนี้ผมขออนุญาตหยุดไว้ที่การเขียนไฟล์นะครับ เพราะการอ่านไฟล์จะมีรายละเอียดพอสมควร


หากเขียนในครั้งนี้ จะทำให้บทความยาวเกินไป แล้วพบกันเรื่องการเขียนไฟล์ฉบับหน้าครับ

1 comment: