การอ่านไฟล์ด้วย Python

บทนำ

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

ในบทความนี้เราจะอธิบายวิธีอ่านไฟล์ด้วย Python ผ่านตัวอย่าง ตัวอย่างบางส่วน ได้แก่ การอ่านไฟล์ทีละบรรทัด เป็นกลุ่ม (จำนวนบรรทัดที่กำหนดในแต่ละครั้ง) และการอ่านไฟล์ในครั้งเดียว นอกจากนี้ เราจะแสดงวิธีการอ่านบรรทัดเฉพาะจากไฟล์ให้คุณทราบเท่านั้น โดยไม่ต้องค้นหาทั้งไฟล์

พื้นฐานของไฟล์ใน Python

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

เมื่อเปิดไฟล์เพื่ออ่าน Python จำเป็นต้องรู้ว่าไฟล์นั้นควรเปิดด้วยระบบอย่างไร มีโหมดการเข้าถึงสองโหมด – การอ่านและการอ่านในโหมดไบนารี ธงที่ใช้คือ 'r'และ 'rb'และต้องระบุเมื่อเปิดไฟล์ด้วย built-in open() การทำงาน. โหมดแรกประกอบด้วยการตีความอักขระพิเศษ เช่น "CR" (การขึ้นบรรทัดใหม่) และ "LF" (การป้อนบรรทัด) เพื่อแสดงถึงการขึ้นบรรทัดใหม่ ในขณะที่โหมดไบนารีช่วยให้คุณอ่านข้อมูลในโหมดดิบ - ซึ่งข้อมูลจะถูกเก็บไว้ตามที่เป็นอยู่ โดยไม่ต้องตีความเพิ่มเติม

เมื่อคุณเปิดไฟล์แล้ว open() ฟังก์ชั่นจะส่งคืนวัตถุไฟล์ให้คุณ วัตถุไฟล์เหล่านี้มีวิธีการเช่น read(), readline(), write(), tell()และ seek(). แม้ว่าบางไฟล์ออบเจ็กต์ (หรืออ็อบเจ็กต์ที่คล้ายไฟล์) จะมีเมธอดมากกว่าที่แสดงในที่นี้ แต่วิธีเหล่านี้มักใช้บ่อยที่สุด ไม่ใช่ทุกอ็อบเจ็กต์ไฟล์จำเป็นต้องใช้เมธอดไฟล์ทั้งหมด

การอ่านไฟล์ทีละบรรทัด

ตัวอย่างแรกได้รับแรงบันดาลใจจากภาษาการเขียนโปรแกรมสองภาษา ได้แก่ C และ C++ อาจเป็นแนวทางที่เข้าใจง่ายที่สุด – เปิดไฟล์โดยใช้ปุ่ม open() ฟังก์ชั่น อ่านไฟล์ทีละบรรทัด โดยใช้โปรแกรม readline() วิธีการและส่งออกบรรทัดทันทีหลังจากอ่าน

ในการใช้งานนี่คือ a while วนซ้ำที่อ่านอย่างต่อเนื่องจากไฟล์ตราบเท่าที่ readline() วิธีช่วยให้ส่งคืนข้อมูล ในกรณีที่ถึงจุดสิ้นสุดของไฟล์ (EOF) ถึง while ลูปหยุดและวัตถุไฟล์ถูกปิด ทำให้ทรัพยากรสำหรับโปรแกรมอื่นใช้:


filename = "test.txt"

filehandle = open(filename, 'r')
while True:
    
    line = filehandle.readline()
    if not line:
        break
    print(line)


filehandle.close()

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

การปรับปรุง โปรโตคอลตัววนซ้ำที่สะดวก ถูกนำมาใช้ใน Python 2.3 สิ่งนี้ช่วยให้คุณลดความซับซ้อนของ readline วน:


filename = "test.txt"
for line in open(filename, 'r'):
    print(line)

ในการใช้งานนี่คือ a for วนร่วมกับ in ตัววนซ้ำ บรรทัดปัจจุบันถูกระบุด้วยความช่วยเหลือของ in iterator อ่านจากไฟล์และเนื้อหาจะถูกส่งออกไปยัง stdout. Python ครอบคลุมการเปิดและปิดไฟล์สำหรับคุณเมื่ออยู่นอกขอบเขต แม้ว่าจะไม่มีประสิทธิภาพ แต่ก็ช่วยให้คุณไม่ต้องจัดการกับตัวจัดการไฟล์อีกต่อไป

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

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


filename = "test.txt"
with open(filename, 'r') as filehandle:
    for line in filehandle:
        print(line)

การรวมกันของ with คำสั่งและ open() คำสั่งเปิดไฟล์เพียงครั้งเดียว ถ้าสำเร็จ for วนซ้ำและเนื้อหาของบรรทัดจะถูกพิมพ์บน stdout.

นอกจากนี้ การใช้ with คำสั่งมีผลข้างเคียง ภายในตัวแปล Python จะสร้าง a try-finally-block เพื่อห่อหุ้มการอ่านจากไฟล์ ตัวอย่างต่อไปนี้แสดงสิ่งที่เกิดขึ้นภายในโดยพื้นฐานใน Python ด้วย with บล็อกรหัส:

try:
    filehandle = open(filename, 'r')
    
finally:
    filehandle.close()

การอ่านไฟล์เป็นเส้นๆ

ถึงตอนนี้ เราได้ประมวลผลไฟล์ทีละบรรทัด สิ่งนี้ค่อนข้างช้าสำหรับไฟล์ขนาดใหญ่และสามารถปรับปรุงได้โดยการอ่านหลายบรรทัดพร้อมกัน เพื่อให้บรรลุเป้าหมายนั้น islice() วิธีการจาก itertools โมดูลเข้ามาเล่น นอกจากนี้ยังทำงานเป็นตัววนซ้ำและส่งกลับกลุ่มข้อมูลที่ประกอบด้วย n เส้น ในตอนท้ายของไฟล์ ผลลัพธ์อาจสั้นลง และสุดท้าย การเรียกจะส่งคืนรายการว่าง:

from itertools import islice

filename = "test.txt"

number_of_lines = 5

with open(filename, 'r') as input_file:
    lines_cache = islice(input_file, number_of_lines)
   
    for current_line in lines_cache:
        print (current_line)

การอ่านบรรทัดเฉพาะจากไฟล์

การใช้วิธีการที่แสดงด้านบนนี้ เรายังดำเนินการอื่นๆ ที่เป็นประโยชน์ได้ เช่น การอ่านบรรทัดเฉพาะจากไฟล์ ในการทำเช่นนี้ เราใช้ตัวนับและพิมพ์บรรทัดที่เหมาะสมเมื่อเรามาถึงในขณะที่วนซ้ำผ่านไฟล์:


filename = "test.txt"

line_number = 3
print (f"line {line_number} of {filename} is: ")

with open(filename, 'r') as filehandle:
current_line = 1
    for line in filehandle:
        if current_line == line_number:
            print(line)
            break
        current_line += 1

สิ่งนี้ควรเข้าใจง่าย แต่ยาวกว่าตัวอย่างก่อนหน้านี้เล็กน้อย สามารถย่อให้สั้นลงได้โดยใช้ปุ่ม ไลน์แคช โมดูล.

ตัวอย่างต่อไปนี้แสดงวิธีการลดความซับซ้อนของโค้ดโดยใช้เครื่องหมาย getline() กระบวนการ. หากหมายเลขบรรทัดที่ร้องขออยู่นอกช่วงของบรรทัดที่ถูกต้องในไฟล์ แสดงว่า getline() method ส่งคืนสตริงว่างแทน:


import linecache

filename = "test.txt"

line_number = 3

line = linecache.getline(filename, line_number)
print (f"line {line_number} of {filename}:")
print (line)

อ่านไฟล์ทั้งหมดในครั้งเดียว

สุดท้ายแต่ไม่ท้ายสุด เราจะดูกรณีที่แตกต่างอย่างมากจากตัวอย่างก่อนหน้านี้ – อ่านไฟล์ทั้งหมดในครั้งเดียว

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

ดูคู่มือเชิงปฏิบัติสำหรับการเรียนรู้ Git ที่มีแนวทางปฏิบัติที่ดีที่สุด มาตรฐานที่ยอมรับในอุตสาหกรรม และเอกสารสรุปรวม หยุดคำสั่ง Googling Git และจริงๆ แล้ว เรียน มัน!


filename = "test.txt"

with open(filename, 'r') as filehandle:
    filecontent = filehandle.read()
    print (filecontent)

Python ยังเสนอ readlines() วิธีการซึ่งคล้ายกับ readline() วิธีการจากตัวอย่างแรก ตรงกันข้ามกับ read(), เนื้อหาไฟล์จะถูกเก็บไว้ในรายการ โดยที่เนื้อหาแต่ละบรรทัดเป็นรายการ:


filename = "test.txt"

with open(filename, 'r') as filehandle:
    filecontent = filehandle.readlines()
    for line in filecontent:
        print (line)

ในขณะที่ readlines() จะอ่านเนื้อหาจากไฟล์จนกว่าจะถึง EOF โปรดทราบว่าคุณสามารถจำกัดปริมาณเนื้อหาที่อ่านได้ด้วยการจัดเตรียม sizehint พารามิเตอร์ ซึ่งเป็นจำนวนไบต์ที่จะอ่าน

สรุป

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

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

ประทับเวลา:

เพิ่มเติมจาก สแต็ค