יום שבת, 17 בדצמבר 2022

הפונקציה id ומעט על פייתון, משתנים וזכרון. [פייתון]

אנחנו חיים בעולם שאנחנו משתמשים המון במשתנה ששמו id, כי מה לעשות אנחנו עובדים המון עם ids 

לפייתון יש פונקציה מובנית בשם id שהיא פונקציה שכל מטרתה היא להראות לנו איזו כתובת בזכרון מאכסנת את האובייקט, לדוגמה: 



בדוגמה שלנו הגדרנו משתנה בשם user ואז העתקנו אותו למשתנה בשם user_ptr שהוא באותה כתובת בזכרון *כרגע*, שימו לב שזה לא מצביע במובן שאנחנו מכירים נניח ב C,   אלא רק לצרכי יעילות השמירה בזכרון, ההצבה היא לאותו מקום בזכרון. לסיום הגדרנו משתנה שלישי בשם cat 

כמו שאפשר לראות הרצה של id על כל אחד מהאובייקטים כצפוי הראה לנו ששני המשתנים הראשונים מצביעים לאותו מקום בזכרון ואילו המשתנה cat (שערכו קוזמו ולא במקרה, כי אין על קוזמו בעולם, החתול של עבדיכם הנאמן) הוא נמצא כמובן במקום אחר בזכרון. 


מה יקרה אם נציב ערך ב id, כי נניח אנחנו מפתחים לוגיקה שזקוקה ל id: 


אז פייתון כמובן מאפשרת לנו לעשות הצבה כזו ולמעשה להפוך את הפונקציה למשתנה מסוג int, כמובן שכצפוי איבדנו את הפונקציה id  המובנית של השפה. והשאלה העולה, אולי פילוסופית במובנים מסוימים,  היא האם זו פעולה שנכון לעשות מבחינת כתיבת קוד ״לפי הספר״.

אפשר, כאלטרנטיבה, לעבוד עם משתנה בשם אחר, כשאופציה שאני אוהב היא משתנה בשם idx. אולי עדיף ככה? 

דעתי הצנועה בסוגיה הזו היא שב- api שחשוף לעולם, תמיד אשתמש ב id בתור פרמטר כשמועבר id מבחוץ, כי זה הדבר הנקי והנכון בעיניי לחשוף החוצה (לעולם שהוא לא בהכרח פייתון  כמובן).  אך בתוך קוד פנימי אני לרוב משתדל להשתמש ב idx במקום. 

אגב, ברגע שעושים מחיקה של המשתנה כלומר,  מריצים del id, הפונקציה id של השפה כמובן עובדת שוב. 

אני חושב שכדאי להכיר את הפונקציה id,  במקרים מסוימים היא תעזור לנו להבין באגים (שיכולים לנבוע משימוש לא נכון בהעתקת משתנים) וגם אפשר לשחק איתה ולזהות איך פייתון מנסה (כלומר, איך האינטרפטר של פייתון מנסה) לשמור על יעילות דרך שימוש חוזר במידע במקום שיכפול של מידע ובכלל להבין קצת יותר איך השפה עובדת.  ראו את הדוגמה הבאה: 



מה קורה כאן?

למעשה פייתון הקצתה לשני המשתנים שלנו את אותו הערך בזכרון, כשהמטרה היא לחסוך בזכרון וליעל קצת את הקוד. אז הדבר שהיינו יכולים לצפות לו הוא ששינוי של המשתנה המקורי ישתקף במשתנה שמצביע לאותו מקום בזכרון, אבל לא כך. פייתון עובדת.

 פייתון שומרת תמיד משתנה שמבצעים לו השמה במקום חדש בזכרון, וזה משרת אותנו היטב, כי במקרה שלנו המשתנים בסופו של דבר  הם באמת שני משתנים שונים ונפרדים. למעשה כל השמה מחדש למשתנה תמיד משנה את המיקום שלו בזכרון. ככה השפה עובדת. וה gc באחריותו מאחורי הקלעים לנקות שאריות (אם אין משתנים אחרים שמשתמשים באותו הערך, כדי לשמור לנו על הזכרון מדליפה לא רצויה. 



אין תגובות:

הוסף רשומת תגובה