io --- สตรีมอินพุต/เอาต์พุต¶
โมดูลนี้ประกอบด้วยประเภทออบเจ็กต์ stream (คล้ายไฟล์) เพิ่มเติม และฟังก์ชันช่วยเหลือ โมดูลนี้เปิดเผย builtin open() พร้อมกับบัฟเฟอร์ข้อความและไบนารีในหน่วยความจำ (StringIO, BytesIO) ที่ใช้งานอินเทอร์เฟซสตรีมมาตรฐาน read/write/seek
ลำดับชั้นเชิงแนวคิด¶
ความแตกต่างจาก CPython
ลำดับชั้นเชิงแนวคิดของคลาสฐานสตรีมถูกทำให้เรียบง่ายขึ้นใน MicroPython ดังที่อธิบายในส่วนนี้
คลาสฐานสตรีม (เชิงนามธรรม) ซึ่งทำหน้าที่เป็นรากฐานสำหรับพฤติกรรมของคลาสคอนกรีตทั้งหมด ยึดถือการแบ่งแยกแบบคู่ (คู่การจำแนก) ไม่กี่ประการใน CPython ใน MicroPython สิ่งเหล่านี้ถูกทำให้เรียบง่ายขึ้นบ้างและเป็นนัยเพื่อให้ได้ประสิทธิภาพสูงขึ้นและประหยัดทรัพยากร
การแบ่งแยกสำคัญประการหนึ่งใน CPython คือสตรีมแบบไม่มีบัฟเฟอร์กับแบบมีบัฟเฟอร์ ใน MicroPython สตรีมทั้งหมดในปัจจุบันไม่มีบัฟเฟอร์ เนื่องจากระบบปฏิบัติการสมัยใหม่ทุกระบบ และแม้แต่ RTOS และไดรเวอร์ระบบไฟล์หลายตัวทำการบัฟเฟอร์อยู่แล้วในฝั่งของตน การเพิ่มบัฟเฟอร์อีกชั้นหนึ่งนั้นไม่เกิดประโยชน์ (ปัญหาที่รู้จักในชื่อ "bufferbloat") และใช้หน่วยความจำอันมีค่าไปโดยเปล่าประโยชน์ โปรดทราบว่ายังมีกรณีที่การบัฟเฟอร์อาจมีประโยชน์ ดังนั้นเราอาจนำการรองรับการบัฟเฟอร์แบบเลือกใช้มาใช้ในภายหลัง
แต่ใน CPython การแบ่งแยกสำคัญอีกประการหนึ่งเกี่ยวข้องกับ "ความมีบัฟเฟอร์" ซึ่งก็คือว่าสตรีมอาจเกิดการอ่าน/เขียนแบบสั้นหรือไม่ การอ่านแบบสั้นคือเมื่อผู้ใช้ขอเช่น 10 ไบต์จากสตรีม แต่ได้รับน้อยกว่า ในทำนองเดียวกันสำหรับการเขียน ใน CPython สตรีมที่ไม่มีบัฟเฟอร์จะมีโอกาสเกิดการดำเนินการสั้นโดยอัตโนมัติ ในขณะที่สตรีมที่มีบัฟเฟอร์จะรับประกันว่าจะไม่เกิดขึ้น พฤติกรรมไม่มีการอ่าน/เขียนสั้นเป็นคุณสมบัติสำคัญ เนื่องจากช่วยให้พัฒนาโปรแกรมที่กระชับและมีประสิทธิภาพมากขึ้น ซึ่งเป็นสิ่งที่พึงปรารถนาอย่างยิ่งสำหรับ MicroPython ดังนั้น แม้ว่า MicroPython จะไม่รองรับสตรีมแบบมีบัฟเฟอร์ แต่ก็ยังรองรับสตรีมแบบไม่มีการดำเนินการสั้น ว่าจะมีการดำเนินการสั้นหรือไม่ขึ้นอยู่กับความต้องการของแต่ละคลาส แต่นักพัฒนาได้รับคำแนะนำอย่างยิ่งให้เลือกใช้พฤติกรรมไม่มีการดำเนินการสั้นด้วยเหตุผลที่กล่าวข้างต้น ตัวอย่างเช่น ซ็อกเก็ต MicroPython ได้รับการรับประกันว่าจะหลีกเลี่ยงการอ่าน/เขียนสั้น จริงๆ แล้ว ณ เวลานี้ไม่มีตัวอย่างคลาสสตรีมแบบการดำเนินการสั้นในคอร์ และคลาสดังกล่าวจะเฉพาะเจาะจงสำหรับฮาร์ดแวร์บางประเภท
พฤติกรรมไม่มีการดำเนินการสั้นจะซับซ้อนขึ้นในกรณีของสตรีมแบบไม่บล็อก โดยพฤติกรรมบล็อกกับไม่บล็อกเป็นการแบ่งแยกอีกประการของ CPython ที่ MicroPython รองรับอย่างเต็มที่ สตรีมแบบไม่บล็อกจะไม่รอข้อมูลทั้งที่จะมาถึงหรือเขียนออก โดยจะอ่าน/เขียนเท่าที่ทำได้ หรือส่งสัญญาณว่าขาดข้อมูล (หรือความสามารถในการเขียนข้อมูล) เห็นได้ชัดว่าสิ่งนี้ขัดแย้งกับนโยบาย "ไม่มีการดำเนินการสั้น" และแน่นอน กรณีของสตรีมแบบไม่บล็อกที่มีบัฟเฟอร์ (และด้วยเหตุนี้จึงไม่มีการดำเนินการสั้น) นั้นซับซ้อนใน CPython ในบางจุดการรวมกันดังกล่าวถูกห้าม ในบางจุดไม่ได้กำหนดหรือไม่ได้รับการจัดทำเอกสาร ในบางกรณีจะทำให้เกิดข้อยกเว้นที่มีรายละเอียดมาก เรื่องนี้ง่ายกว่ามากใน MicroPython: สตรีมแบบไม่บล็อกมีความสำคัญสำหรับการดำเนินการแบบอะซิงโครนัสที่มีประสิทธิภาพ ดังนั้นคุณสมบัตินี้จึงมีความสำคัญเหนือกว่า "ไม่มีการดำเนินการสั้น" ดังนั้น แม้ว่าสตรีมแบบบล็อกจะหลีกเลี่ยงการอ่าน/เขียนสั้นเมื่อทำได้ (กรณีเดียวที่จะได้รับการอ่านสั้นคือถึงจุดสิ้นสุดของไฟล์ หรือในกรณีที่เกิดข้อผิดพลาด (แต่ข้อผิดพลาดไม่ส่งคืนข้อมูลสั้น แต่จะยกข้อยกเว้น)) สตรีมแบบไม่บล็อกอาจสร้างข้อมูลสั้นเพื่อหลีกเลี่ยงการบล็อกการดำเนินการ
การแบ่งแยกสุดท้ายคือสตรีมไบนารีกับสตรีมข้อความ MicroPython แน่นอนว่ารองรับสิ่งเหล่านี้ แต่ในขณะที่ CPython สตรีมข้อความมีบัฟเฟอร์โดยเนื้อแท้ แต่ใน MicroPython ไม่เป็นเช่นนั้น (แท้จริงแล้ว นั่นเป็นหนึ่งในกรณีที่เราอาจนำการรองรับการบัฟเฟอร์มาใช้)
โปรดทราบว่าเพื่อประสิทธิภาพ MicroPython ไม่มีคลาสฐานนามธรรมที่สอดคล้องกับลำดับชั้นข้างต้น และไม่สามารถนำคลาสสตรีมไปใช้งาน หรือสร้างคลาสย่อยใน Python บริสุทธิ์ได้
ฟังก์ชัน¶
คลาส¶
- class io.IOBase¶
คลาสฐานสำหรับออบเจ็กต์สตรีม ("คล้ายไฟล์") คลาสย่อยคอนกรีตจะนำเมธอด I/O ระดับต่ำด้านล่างไปใช้งาน (
readinto,write,ioctl) รันไทม์จะสร้างโปรโตคอลสตรีมระดับสูง (read,readline,readlines,close, การวนซ้ำ) บนพื้นฐานของสิ่งเหล่านี้ ดังนั้นทุก instance ของสตรีมรองรับเมธอดเหล่านั้นแม้ว่าคลาสย่อยจะไม่ได้กำหนดไว้เมธอดสำหรับการนำไปใช้งาน (แทนที่เมธอดเหล่านี้ในคลาสย่อย):
- readinto(buf: bytearray) int | None¶
อ่านไบต์ลงในบัฟเฟอร์ buf ที่เขียนได้ ส่งคืนจำนวนไบต์ที่อ่าน
0เมื่อสิ้นสุดสตรีม หรือNoneหากไม่มีข้อมูลในขณะนี้ (สำหรับสตรีมแบบไม่บล็อก)
- write(buf: bytes) int | None¶
เขียนไบต์ใน buf ส่งคืนจำนวนไบต์ที่เขียน หรือ
Noneหากไม่สามารถเขียนได้ในขณะนี้ (สำหรับสตรีมแบบไม่บล็อก)
- ioctl(request: int, arg: int) int¶
ควบคุมสตรีม/อุปกรณ์ที่อยู่ด้านล่าง request คือหนึ่งในรหัสคำขอ
MP_STREAM_*ส่งคืนค่าที่ไม่ติดลบเมื่อสำเร็จ หรือค่าerrnoติดลบเมื่อเกิดข้อผิดพลาด
เมธอดโปรโตคอลสตรีม (มีอยู่ในทุก instance ของสตรีม):
- read(size: int = -1)¶
อ่านและส่งคืนสูงสุด size ไบต์ (หรืออักขระในโหมดข้อความ) หาก size ถูกละเว้นหรือเป็นลบ จะอ่านจนถึงสิ้นสุดสตรีม ส่งคืน
bytesสำหรับสตรีมไบนารี และstrสำหรับสตรีมข้อความ ผลลัพธ์ว่างแสดงว่าสิ้นสุดสตรีมแล้ว
- readline(size: int = -1)¶
อ่านและส่งคืนหนึ่งบรรทัด รวมถึงอักขระขึ้นบรรทัดใหม่ที่ท้ายหากมี หาก size ถูกระบุ จะอ่านสูงสุด size ไบต์ (หรืออักขระ) ส่งคืน
bytes/strว่างเมื่อสิ้นสุดสตรีม
- readlines() list¶
อ่านจนถึงสิ้นสุดสตรีมและส่งคืน
listของบรรทัด โดยแต่ละบรรทัดมีอักขระขึ้นบรรทัดใหม่ที่ท้าย
- close() None¶
ปิดสตรีมและปล่อยทรัพยากรที่อยู่ด้านล่าง การดำเนินการบนสตรีมที่ปิดแล้วจะยกข้อยกเว้น
OSError(หรือValueErrorสำหรับสตรีมในหน่วยความจำ)
- seek(offset: int, whence: int = 0) int¶
เปลี่ยนตำแหน่งสตรีมปัจจุบันเป็น offset ไบต์สัมพันธ์กับ whence (
0= ต้นสตรีม,1= ตำแหน่งปัจจุบัน,2= ท้ายสตรีม) ส่งคืนตำแหน่งสัมบูรณ์ใหม่ ยกข้อยกเว้นOSErrorบนสตรีมที่ไม่รองรับการค้นหา
- flush() None¶
ล้างบัฟเฟอร์การเขียน โดยส่งข้อมูลที่รอดำเนินการไปยังอุปกรณ์หรือไฟล์ที่อยู่ด้านล่าง ไม่มีผลใดๆ บนสตรีมที่ไม่มีบัฟเฟอร์
การวนซ้ำบนสตรีมโดยตรงจะให้หนึ่งบรรทัดต่อการวนซ้ำ ซึ่งเทียบเท่ากับการเรียก
readline()ในลูปจนกว่าจะได้รับ sentinel ปลายสตรีมแบบบรรทัดว่าง สตรีมยังรองรับโปรโตคอล context-manager ดังนั้นwith open(...) as f:จะปิดสตรีมโดยอัตโนมัติNote
โมดูลสตรีมของ MicroPython ยังเปิดเผย C helper ที่มีคำต่อท้าย "1" ได้แก่
mp_stream_read1_obj,mp_stream_readinto1_obj, และmp_stream_write1_objที่ทำการเรียก I/O ด้านล่างเพียงครั้งเดียวแทนที่จะวนซ้ำจนกว่าคำขอจะได้รับการตอบสนองอย่างสมบูรณ์ สิ่งเหล่านี้ใช้ภายในโดยคลาสเช่นmachine.UARTเพื่อนำread/writeของตัวเองไปใช้งาน แต่ไม่มีคลาสสตรีมมาตรฐานใดที่ผูกมันเป็นเมธอดread1/readinto1/write1ที่เรียกได้จาก Python
- class io.StringIO(string: str = '')¶
ออบเจ็กต์คล้ายไฟล์ในหน่วยความจำสำหรับอินพุต/เอาต์พุตโหมดข้อความ (คล้ายกับไฟล์ปกติที่เปิดด้วยตัวปรับแต่ง "t") สามารถระบุเนื้อหาเริ่มต้นด้วยพารามิเตอร์ string (ซึ่งควรเป็นสตริงปกติ) Instance ยังรองรับโปรโตคอล context-manager (ใช้ได้ใน
withstatement)- read(size: int = -1) str¶
อ่านและส่งคืนสูงสุด size อักขระ หาก size ถูกละเว้นหรือเป็นลบ จะอ่านและส่งคืนเนื้อหาที่เหลือทั้งหมด
- readinto(buf: bytearray) int¶
อ่านลงในบัฟเฟอร์ buf ที่จัดสรรไว้ล่วงหน้าและสามารถเขียนได้ แล้วส่งคืนจำนวนไบต์ที่อ่าน
- seek(offset: int, whence: int = 0) int¶
เปลี่ยนตำแหน่งสตรีมเป็น offset สัมพันธ์กับ whence (
0= ต้น,1= ปัจจุบัน,2= ท้าย) แล้วส่งคืนตำแหน่งสัมบูรณ์ใหม่
- close() None¶
ปิดสตรีมและปล่อยบัฟเฟอร์ด้านล่าง การดำเนินการเพิ่มเติมบนสตรีมที่ปิดแล้วจะยกข้อยกเว้น
ValueError
- class io.StringIO(alloc_size: int)
สร้างออบเจ็กต์
StringIOว่างที่จัดสรรไว้ล่วงหน้าเพื่อรองรับสูงสุด alloc_size ไบต์ ดังนั้นการเขียนถึงจำนวนไบต์นั้นจะไม่จัดสรรบัฟเฟอร์ใหม่ (หลีกเลี่ยงสถานการณ์หน่วยความจำไม่พอหรือการกระจายตัวของหน่วยความจำ) ตัวสร้างนี้เป็นส่วนขยาย MicroPython ที่แนะนำเฉพาะสำหรับกรณีพิเศษและไลบรารีระดับระบบ ไม่ใช่สำหรับแอปพลิเคชันผู้ใช้ทั่วไปความแตกต่างจาก CPython
ตัวสร้างนี้เป็นส่วนขยาย MicroPython
- read(size: int = -1) str
อ่านและส่งคืนสูงสุด size อักขระ หาก size ถูกละเว้นหรือเป็นลบ จะอ่านและส่งคืนเนื้อหาที่เหลือทั้งหมด
- readinto(buf: bytearray) int
อ่านลงในบัฟเฟอร์ buf ที่จัดสรรไว้ล่วงหน้าและสามารถเขียนได้ แล้วส่งคืนจำนวนไบต์ที่อ่าน
- seek(offset: int, whence: int = 0) int
เปลี่ยนตำแหน่งสตรีมเป็น offset สัมพันธ์กับ whence (
0= ต้น,1= ปัจจุบัน,2= ท้าย) แล้วส่งคืนตำแหน่งสัมบูรณ์ใหม่
- tell() int
ส่งคืนตำแหน่งสตรีมปัจจุบัน
- flush() None
ล้างบัฟเฟอร์การเขียน ไม่มีผลใดๆ สำหรับสตรีมในหน่วยความจำ
- close() None
ปิดสตรีมและปล่อยบัฟเฟอร์ด้านล่าง การดำเนินการเพิ่มเติมบนสตรีมที่ปิดแล้วจะยกข้อยกเว้น
ValueError
- getvalue() str
ส่งคืนเนื้อหาปัจจุบันของบัฟเฟอร์ด้านล่าง
- class io.BytesIO(string: bytes = b'')¶
ออบเจ็กต์คล้ายไฟล์ในหน่วยความจำสำหรับอินพุต/เอาต์พุตโหมดไบนารี (คล้ายกับไฟล์ปกติที่เปิดด้วยตัวปรับแต่ง "b") สามารถระบุเนื้อหาเริ่มต้นด้วยพารามิเตอร์ string (ซึ่งควรเป็นออบเจ็กต์ bytes) Instance ยังรองรับโปรโตคอล context-manager (ใช้ได้ใน
withstatement)- read(size: int = -1) bytes¶
อ่านและส่งคืนสูงสุด size ไบต์ หาก size ถูกละเว้นหรือเป็นลบ จะอ่านและส่งคืนเนื้อหาที่เหลือทั้งหมด
- readinto(buf: bytearray) int¶
อ่านลงในบัฟเฟอร์ buf ที่จัดสรรไว้ล่วงหน้าและสามารถเขียนได้ แล้วส่งคืนจำนวนไบต์ที่อ่าน
- seek(offset: int, whence: int = 0) int¶
เปลี่ยนตำแหน่งสตรีมเป็น offset สัมพันธ์กับ whence (
0= ต้น,1= ปัจจุบัน,2= ท้าย) แล้วส่งคืนตำแหน่งสัมบูรณ์ใหม่
- close() None¶
ปิดสตรีมและปล่อยบัฟเฟอร์ด้านล่าง การดำเนินการเพิ่มเติมบนสตรีมที่ปิดแล้วจะยกข้อยกเว้น
ValueError
- class io.BytesIO(alloc_size: int)
สร้างออบเจ็กต์
BytesIOว่างที่จัดสรรไว้ล่วงหน้าเพื่อรองรับสูงสุด alloc_size ไบต์ ดังนั้นการเขียนถึงจำนวนไบต์นั้นจะไม่จัดสรรบัฟเฟอร์ใหม่ (หลีกเลี่ยงสถานการณ์หน่วยความจำไม่พอหรือการกระจายตัวของหน่วยความจำ) ตัวสร้างนี้เป็นส่วนขยาย MicroPython ที่แนะนำเฉพาะสำหรับกรณีพิเศษและไลบรารีระดับระบบ ไม่ใช่สำหรับแอปพลิเคชันผู้ใช้ทั่วไปความแตกต่างจาก CPython
ตัวสร้างนี้เป็นส่วนขยาย MicroPython
- read(size: int = -1) bytes
อ่านและส่งคืนสูงสุด size ไบต์ หาก size ถูกละเว้นหรือเป็นลบ จะอ่านและส่งคืนเนื้อหาที่เหลือทั้งหมด
- readinto(buf: bytearray) int
อ่านลงในบัฟเฟอร์ buf ที่จัดสรรไว้ล่วงหน้าและสามารถเขียนได้ แล้วส่งคืนจำนวนไบต์ที่อ่าน
- seek(offset: int, whence: int = 0) int
เปลี่ยนตำแหน่งสตรีมเป็น offset สัมพันธ์กับ whence (
0= ต้น,1= ปัจจุบัน,2= ท้าย) แล้วส่งคืนตำแหน่งสัมบูรณ์ใหม่
- tell() int
ส่งคืนตำแหน่งสตรีมปัจจุบัน
- flush() None
ล้างบัฟเฟอร์การเขียน ไม่มีผลใดๆ สำหรับสตรีมในหน่วยความจำ
- close() None
ปิดสตรีมและปล่อยบัฟเฟอร์ด้านล่าง การดำเนินการเพิ่มเติมบนสตรีมที่ปิดแล้วจะยกข้อยกเว้น
ValueError
- getvalue() bytes
ส่งคืนเนื้อหาปัจจุบันของบัฟเฟอร์ด้านล่าง