למה זה לא מתרסק (או: בעיות שלא רואים)

07/01/2021

כל החיים לימדו אותי שצריך לסגור קובץ אחרי שפותחים אותו כי אחרת אתה לוקח יותר מדי File Handlers ממערכת ההפעלה ובסוף הם ייגמרו והתוכנית תתרסק. ועוד הם אמרו שב Python אני יכול להשתמש ב with כדי שהקובץ ייסגר אוטומטית ולא יהיו לי בעיות. אז יום אחד הלכתי לבדוק את הסיפור הזה וכתבתי את הקוד הבא:

for _ in range(100_000):
    fout = open('output.txt', 'w')
    fout.write("hahaha\n")

מאחר ומספר ה File Handlers הפתוחים בלינוקס שלי מוגבל ל 1024, ציפיתי להתרסקות מהירה. היא לא הגיעה.

מחשבים רוצים לעזור (חוץ מ C++, אבל היא באמת מסיפור אחר), ובמקרה של פייתון הניסיון הזה מתבטא בזה שפייתון שמה לב שכל איטרציה של הלולאה מאבדת את הגישה ל File Handle הקודם שנוצר ולכן מרשה לעצמה לסגור את הקובץ, גם בלי close וגם בלי with.

האם זה אומר שכדאי לי להתרגל לכתוב כך קוד? אני לא בטוח. יש תוכניות ששומרות הרבה אוביקטים בזיכרון ושם יכול להיות שפייתון לא ימחק את ה File Handles שיצרנו כי התוכנית עדיין שומרת מצביע אליהם. אולי יותר מטרידה האפשרות שקוד שמופיע במערכת ישתכפל (כי מתכנתים רגילים לעשות copy-paste ממקומות אחרים בקוד) ויגיע למקומות בהם הוא כן יוביל לזליגת קבצים פתוחים.

לקריאה נוספת בנושא שווה לקרוא את הפוסט הבא של ראובן לרנר שגם עשה ניסויים עם מימושים נוספים של פייתון (pypy ו jython): https://lerner.co.il/2015/01/18/dont-use-python-close-files-answer-depends/.