io — זרמי קלט/פלט¶
מודול זה מכיל סוגים נוספים של אובייקטי stream (דמויי קובץ) ופונקציות עזר. הוא חושף את הבילט-אין 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¶
מחלקת בסיס לאובייקטי זרם (”דמויי קובץ“). מחלקות משנה קונקרטיות מממשות את שיטות הקלט/פלט ברמה הנמוכה שלהלן (
readinto,write,ioctl); סביבת הריצה בונה מעליהן את פרוטוקול הזרם ברמה הגבוהה יותר (read,readline,readlines,close, איטרציה), כך שכל מופע זרם תומך בשיטות אלה גם כאשר מחלקת המשנה אינה מגדירה אותן.שיטות מימוש (דרסו אותן במחלקת משנה):
- 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שלילי בשגיאה.
שיטות פרוטוקול הזרם (זמינות בכל מופע זרם):
- read(size: int = -1)¶
קריאה והחזרה של עד size בתים (או תווים, במצב טקסט). אם size מושמט או שלילי, הקריאה נמשכת עד סוף הזרם. מחזירה
bytesעבור זרמים בינאריים ו-strעבור זרמי טקסט; תוצאה ריקה מציינת את סוף הזרם.
- readline(size: int = -1)¶
קריאה והחזרה של שורה אחת, כולל תו השורה החדשה הסופי אם קיים. אם size ניתן, נקראים לכל היותר size בתים (או תווים). מחזירה
bytes/strריקים בסוף הזרם.
- close() None¶
סגירת הזרם ושחרור כל המשאבים הבסיסיים. פעולות על זרם סגור מעלות
OSError(אוValueErrorעבור זרמים בזיכרון).
- seek(offset: int, whence: int = 0) int¶
שינוי מיקום הזרם הנוכחי ל-offset בתים יחסית ל-whence (
0= תחילת הזרם,1= המיקום הנוכחי,2= סוף הזרם). החזרת המיקום המוחלט החדש. מעלהOSErrorעל זרם שאינו ניתן לחיפוש מיקום.
- flush() None¶
ריקון כל חוצצי הכתיבה, ודחיפת נתונים ממתינים אל ההתקן או הקובץ הבסיסי. ללא השפעה על זרמים שאינם מבצעים חציצה.
איטרציה ישירה על זרם מפיקה שורה אחת בכל איטרציה – שקול לקריאה ל-
readline()בלולאה עד שמוחזר ערך הסימון של סוף-זרם (שורה ריקה). זרם תומך גם בפרוטוקול מנהל ההקשר, כך ש-with open(...) as f:סוגר את הזרם אוטומטית.הערה
מודול הזרמים של MicroPython חושף גם פונקציות עזר ב-C בעלות סיומת ”1“
mp_stream_read1_obj,mp_stream_readinto1_objו-mp_stream_write1_objשמבצעות קריאת קלט/פלט בסיסית אחת במקום ללולל עד שהבקשה מסופקת במלואה. הן משמשות פנימית מחלקות כגוןmachine.UARTלמימוש ה-read/writeשלהן – אך אף מחלקת זרם סטנדרטית אינה קושרת אותן כשיטותread1/readinto1/write1הניתנות לקריאה מ-Python.
- class io.StringIO(string: str = '')¶
אובייקט דמוי קובץ בזיכרון עבור קלט/פלט במצב טקסט (בדומה לקובץ רגיל שנפתח עם המאפיין ”t“). ניתן לציין תוכן התחלתי באמצעות הפרמטר string (שאמור להיות מחרוזת רגילה). מופעים תומכים גם בפרוטוקול מנהל ההקשר (ניתן לשימוש בהוראת
with).- read(size: int = -1) str¶
קריאה והחזרה של עד size תווים. אם size מושמט או שלילי, נקרא ומוחזר כל התוכן הנותר.
- 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 מושמט או שלילי, נקרא ומוחזר כל התוכן הנותר.
- 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). מופעים תומכים גם בפרוטוקול מנהל ההקשר (ניתן לשימוש בהוראת
with).- read(size: int = -1) bytes¶
קריאה והחזרה של עד size בתים. אם size מושמט או שלילי, נקרא ומוחזר כל התוכן הנותר.
- 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 מושמט או שלילי, נקרא ומוחזר כל התוכן הנותר.
- seek(offset: int, whence: int = 0) int
שינוי מיקום הזרם ל-offset יחסית ל-whence (
0= התחלה,1= נוכחי,2= סוף) והחזרת המיקום המוחלט החדש.
- tell() int
החזרת מיקום הזרם הנוכחי.
- flush() None
ריקון חוצצי הכתיבה. ללא השפעה עבור זרם בזיכרון.
- close() None
סגירת הזרם ושחרור החוצץ הבסיסי. פעולות נוספות על זרם סגור מעלות
ValueError.
- getvalue() bytes
החזרת התוכן הנוכחי של החוצץ הבסיסי.