φυβλαςのβλογ
phyblas的博客



ภาษา python เบื้องต้น บทที่ ๑๘: การเขียนข้อมูลลงไฟล์
เขียนเมื่อ 2016/03/05 23:10
แก้ไขล่าสุด 2024/02/22 11:04
 

ในบทที่แล้วได้พูดถึงการเปิดไฟล์เพื่ออ่านไปแล้ว

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



การเปิดไฟล์สำหรับเขียน

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

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

หาก open ไฟล์ในโหมด w จะพบว่าไฟล์นั้นถูกสร้างขึ้นมาทันทีหากมันไม่ได้มีตัวตนอยู่แต่แรก
f = open('xxxx.txt','w',encoding='utf-8')
f.close()

ลองไปดูจะพบว่ามีไฟล์ชื่อ xxxx.txt โผล่มาในโฟลเดอร์เดียวกับไฟล์โปรแกรม และภายในว่างเปล่าไม่มีอะไร

โหมด w กับ a นั้นจะต่างกันตรงที่ว่าในกรณีที่ไฟล์เดิมมีตัวตนอยู่แล้วถ้าเป็นโหมด w ไฟล์จะถูกเขียนทับใหม่ทันที แต่ถ้าเป็น a จะเป็นการเขียนต่อจากไฟล์เดิม

การเขียนไฟล์ก็ต้องเลือกรูปแบบการเอนโค้ดเช่นกัน ในที่นี้ใช้เป็น utf-8 เช่นเคย



คำสั่งเขียนไฟล์

มี ๒ เมธอดที่ใช้ในการเขียนไฟล์ คือ .write กับ .writelines ข้อแตกต่างคือ .write จะใช้กับสายอักขระอันเดียว แต่ .writelines จะใช้กับลิสต์ของสายอักขระ

กรณีที่ใช้กับสายอักขระเดียวยาวต่อเนื่อง จะใช้ .write หรือ .writelines ก็ได้เหมือนกันทั้งคู่
s = '''เวลาที่เข้าหาผู้อื่น ให้มีหัวใจที่อบอุ่นดั่งฤดูใบไม้ผลิ
เวลาที่ทำงาน ให้มีหัวใจที่เร่าร้อนดั่งฤดูร้อน
เวลาที่คิดอะไร ให้มีหัวใจที่แจ่มใสดั่งฤดูใบไม้ร่วง
เวลาที่เผชิญหน้ากับตัวเอง ให้มีหัวใจที่เข้มงวดดั่งฤดูหนาว'''
f = open('samejima.txt','w',encoding='utf-8')
f.write(s)
#หรือ f.writelines(s)
f.close()
(ที่มาของข้อความ)

แต่ถ้ามีสายอักขระหลายๆอันแยกกันอยู่จะใช้ได้แต่ .writelines เช่น
s = ['เวลาที่เข้าหาผู้อื่น ให้มีหัวใจที่อบอุ่นดั่งฤดูใบไม้ผลิ', 'เวลาที่ทำงาน ให้มีหัวใจที่เร่าร้อนดั่งฤดูร้อน', 'เวลาที่คิดอะไร ให้มีหัวใจที่แจ่มใสดั่งฤดูใบไม้ร่วง', 'เวลาที่เผชิญหน้ากับตัวเอง ให้มีหัวใจที่เข้มงวดดั่งฤดูหนาว']
f = open('samejima.txt','w',encoding='utf-8')
f.writelines(s)
f.close()

เพียงแต่ว่าจะไม่มีการเว้นบรรทัดให้ระหว่างสายอักขระแต่ละท่อน ถ้าต้องการก็ต้องเพิ่มเอาเอง

ถ้าจะใช้ .write ก็อาจใช้เป็น f.write('\n'.join(s)) คือใช้เมธอด .join เพื่อรวมสายอักขระเข้าด้วยกันโดยมีการขึ้นบรรทัดใหม่เป็นตัวแบ่ง

หรืออาจจะเขียนต่อๆกันไปเลยก็ได้ การใช้คำสั่ง .write หลายครั้งจะเป็นการเขียนต่อไปเรื่อยๆ โดยจะไม่มีการขึ้นบรรทัดใหม่ให้ดังนั้นต้องเติม \n ไปด้วย
for a in s:
    f.write(a+'\n')

สิ่งที่จะเขียนได้นั้นต้องเป็นสายอักขระเท่านั้น หากไม่ใช่สายอักขระก็ต้องแปลงก่อน

ตัวอย่าง โปรแกรมเขียนเลข 1 ถึง 10000 ลงไฟล์
f = open('10000.txt','w',encoding='utf-8')
for i in range(1,10001):
    f.write('|%d|'%i)
    if(i%100==0): f.write('\n') # ขึ้นบรรทัดใหม่ถ้านับถึง 100
f.close()

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

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

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



การคัดลอกไฟล์

เมื่อสามารถเปิดอ่านและสามารถเขียนไฟล์ได้แล้ว ต่อไปสิ่งที่จะทำได้ตามมาอย่างไม่ยากก็คือการนำข้อมูลจากไฟล์หนึ่งคัดลอกไปลงในอีกไฟล์ ซึ่งก็คือการอ่านไฟล์หนึ่ง ดึงข้อมูลมา แล้วก็นำไปเขียนในอีกไฟล์ ลองดูตัวอย่าง
f1 = open('nishikaze.txt','r',encoding='utf-8') # เปิดไฟล์ต้นฉบับ
f2 = open('nishikaze2.txt','w',encoding='utf-8') # กำหนดไฟล์ใหม่ที่จะเขียน
a = f1.read() # นำข้อมูลจากไฟล์ต้นฉบับมาเก็บในตัวแปร
f2.write(a) # นำข้อมูลจากตัวแปรมาเขียนลงในไฟล์ใหม่
f1.close() # ปิดไฟล์ต้นฉบับ
f2.close() # ปิดไฟล์ที่เขียนเสร็จ

เท่านี้ก็จะได้ไฟล์ใหม่ที่เหมือนกับไฟล์ต้นฉบับทุกประการ

แต่ความจริงแล้วนอกจากนี้ยังมีอีกวิธีที่ง่ายกว่านั้น นั่นคือใช้ฟังก์ชัน copyfile ในมอดูล shutil
import shutil
shutil.copyfile('nishikaze.txt', 'nishikaze2.txt') 

นอกจากนี้ยังมีฟังก์ชัน move เอาไว้ย้ายไฟล์
import shutil
shutil.move('nishikaze2.txt', 'nishikaze3.txt') 

เท่านี้ข้อมูลจากไฟล์เดิมก็ย้ายไปอยู่ในไฟล์ชื่อใหม่

แค่การคัดลอกมาทั้งหมดอาจดูง่ายไปไม่ค่อยมีอะไร เราลองมาทำอะไรที่ต้องออกแรงมากกว่านั้นสักหน่อย

ต่อไปเป็นการนำข้อความจากไฟล์ต้นฉบับมาแตกออกเป็นไฟล์ย่อยแบ่งทีละบรรทัด
f = open('nishikaze.txt','r',encoding='utf-8') # เปิดไฟล์ต้นฉบับ
i = 1
for r in f: # วนซ้ำเพื่อแยกวิเคราะห์ทีละบรรทัด
    if(r=='\n'): continue # หากบรรทัดไหนว่างเปล่าก็ข้ามไปเลย ไม่ต้องสร้างไฟล์ บรรทัดที่ว่างคือบรรทัดที่มีแต่ \n คือคำสั่งขึ้นบรรทัดใหม่
    fw = open('n%02d.txt'%i,'w',encoding='utf-8') # สร้างไฟล์ใหม่ ตั้งชื่อเป็น n ตามด้วยหมายเลข
    fw.writelines(r) # เขียนข้อมูลที่อ่านได้ในบรรทัดนั้นลงไฟล์
    fw.close() # ปิดไฟล์ที่เขียน
    i += 1
f.close() # ปิดไฟล์ต้นฉบับ 



การจัดเก็บข้อมูลเพื่อใช้งาน

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

เราอาจเก็บข้อมูลในลักษณะคล้ายตารางโดยแยกเป็นแถวและมีการเว้นวรรคระหว่างข้อมูลแต่ละตัว

ยกตัวอย่าง เช่นสร้างระบบบันทึกคะแนนสอบโดยให้นักเรียนแต่ละคนป้อนคะแนนสอบแต่ละวิชาแล้วข้อมูลก็ถูกบันทึกลงไปเรื่อยๆ
rahat = input('ป้อนรหัสผู้สอบ: ')
physics = input('คะแนนฟิสิกส์: ')
chemi = input('คะแนนเคมี: ')
chiwa = input('คะแนนชีวะ: ')
f = open('khanaen.txt','a',encoding='utf-8')
f.write('%s %s %s %s\n'%(rahat,physics,chemi,chiwa))
f.close()

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

สมมุติว่ามีนักศึกษามาบันทึกคะแนนแล้วทั้งหมด ๓ คน ไฟล์ก็จะออกมาในลักษณะนี้
590001 90 76 84
590003 99 90 88
590007 80 92 100

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

เช่นเอาข้อมูลที่ได้นี้มาหาค่าต่ำสุด สูงสุด และค่าเฉลี่ย
f = open('khanaen.txt','r',encoding='utf-8')
physics = []
chemi = []
chiwa = []
for s in f:
    a = s.split()
    physics += [int(a[1])]
    chemi += [int(a[2])]
    chiwa += [int(a[3])]
f.close()
print('คะแนนฟิสิกส์ ต่ำสุด=%d, สูงสุด=%d, เฉลี่ย=%.2f'%(min(physics),max(physics),sum(physics)/len(physics)))
print('คะแนนเคมี ต่ำสุด=%d, สูงสุด=%d, เฉลี่ย=%.2f'%(min(chemi),max(chemi),sum(chemi)/len(chemi)))
print('คะแนนชีววิทยา ต่ำสุด=%d, สูงสุด=%d, เฉลี่ย=%.2f'%(min(chiwa),max(chiwa),sum(chiwa)/len(chiwa)))

บางครั้งตัวกั้นข้อมูลก็อาจใช้แท็บ \t หรือในกรณีไฟล์ชนิด .csv จะกั้นด้วยจุลภาค ,

จะใช้เป็นอะไรก็ได้ แต่เวลาเปิดอ่านข้อมูลก็ต้องรู้และระบุตัวแยกให้ถูกต้อง



สรุปเนื้อหา
  • การเขียนไฟล์ก็คล้ายกับการอ่านไฟล์ ต้องเปิดไฟล์ขึ้นมาก่อน โดยต้องเลือกโหมดเป็น w หรือ a
  • w กับ a ต่างกันตรงที่ w เป็นการเขียนทับ ส่วน a เป็นการเขียนต่อ
  • เมธอดที่ใช้เขียนคือ write และ writelines
  • write ใช้กับสายอักขระ ส่วน writelines ใช้กับลิสต์ของสายอักขระ
  • การคัดลอกไฟล์ทำได้โดยเปิดไฟล์ขึ้นมาอ่านแล้วเขียนใส่อีกไฟล์ หรือใช้ shutil.copyfile ก็ได้
  • สามารถใช้การอ่านและเขียนไฟล์เพื่อจัดการกับข้อมูลอย่างเป็นระบบได้


อ้างอิง
http://docs.python.jp/3/library/functions.html
http://www.ops.dti.ne.jp/ironpython.beginner/textfile.html
http://www.yukun.info/blog/2008/09/python-file-write-writelines.html




-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

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

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  查看日志

  推荐日志

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ