כתובות של קבועים בפייתון

היי, אני רוצה שוב להודות לסגל הקורס עח העבודה הקשה שהם משקיעים למענינו. מדובר בקורס מאוד איכותי!

רציתי בבקשה לשאול, האם כאשר אני יוצר שני קבועים שווים (כמו שני מספרים שווים, סטרינגים שווים ורשימות שוות) הכתובת בזיכרון של שני האיברים השווים לא אמורה להיות שווה?

בצילום שאני מעלה יצאו לי שתי כתובות שונות.

דבר שני, כאשר אני מריץ שוב את התכנית, כל אחת מן הכתובות משתנה לכתובת חדשה. מדוע זה כך?

תודה רבה! קורס מדהים!

רשימות בפייתון הן אובייקטים מסוג mutable, וככאלה, כל פעם שמשנים בהן משהו, הID שלהן משתנה, ולכן לא ניתן לסמוך על זה.
תקרא קצת על hashable, כדי לדעת אילו אובייקטים משתנים ואילו לא משתנים.
רמז - אם אתה שומר מספרים, הID שלהם יהיה זהה, אם זה אותו מספר.

לייק 1

נכנסת לשאלה סופר כבדה X: אנסה לענות בקצרה. עבור שאר באי האשכול ללא ידע מקדים: כשאנחנו אומרים “הכתובת בזיכרון” אנחנו מתכוונים ללאיפה מצביע הלייזר, וכשאנחנו אומרים “כתובת בזיכרון […] שווה” – שני לייזרים שמצביעים לאותו מקום.

  1. כל העניינים של איך מתנהג הזיכרון תלוי בגדול במימוש של פייתון. פייתון היא בסופו של דבר “סטנדרט” יותר מאשר שפה (כמו מסמך תקינה כזה), ויש כמה מנועים שמממשים את התקינה הזו. אנחנו עובדים עם מנוע שנקרא CPython שרוב העולם משתמש בו, אבל יש עוד כמה מנועים כמו pypy, IronPython, Jython ועוד, שבכל אחד ההתנהגות של הזיכרון יכולה להיות אחרת. למעשה, התנהגות הזיכרון לא מובטחת לך אפילו בין גרסאות שונות של CPython (אלא אם זה ממש כתוב כחלק מהתקינה, כמובן).
  2. פייתון מנסה לייעל את הזיכרון בכל מני מקרים, ולכן לפעמים באופן די מפתיע כתובות הזיכרון של שני דברים שונים יהיו זהות. זה קורה בד"כ במבנים שהם Immutables. לדוגמה, CPython תשמור את כל המספרים מ־-4 ועד 256 בכתובות קבועות.
  3. במבנים שהם Mutables זה מאוד מסוכן לעשות משחקי זיכרון כמו שהצגת, ולכן הדוגמה שלך על רשימות לא עובדת. זו החלטה שהתקבלה בכוונה. דמיין לעצמך שהיית מגדיר 2 רשימות זהות במקומות שונים בקוד, היית עושה על אחת מהן append וגם השנייה הייתה משתנה. לא בריא ולא התנהגות שאפשר לצפות מראש.
  4. אם לסבך דברים, ל־CPython יש מנגנון שמנסה לייעל את הזיכרון של שמירת מחרוזות (שהן מבנה Immutable, כן?) והוא מבצע string interning. ניתן לקרוא עוד על ה־String Interning של פייתון כאן.
5 לייקים

תודה רבה לשניכם! ים תודה רבה על התשובה המושקעת. ״מנוע״ זה מונח רשמי? מה זה בעצם מנוע?

2 לייקים

השאלתי משפות אחרות, המינוח הרשמי הוא “מימוש” (implementation)

2 לייקים

מה בעצם בא לדרוש אותו סטנדרט? האם מה שמגדיר שפת תכנות אינו אלא הדקדוק שלה?

למעשה מה שקורה עם פייתון הוא מצב מעט מוזר.

כשאני אומר “תהליך תקינה” רוב האנשים מדמיינים כברירת־מחדל תהליך כמו שקורה ב־JavaScript:

  1. יש גוף תקינה רשמי (ECMA) שמקבל החלטות באופן מסודר
  2. מוציאים כל תקופה מסמך תקינה שכתוב באופן הכי מסודר ומובהק שרק אפשר (טריוויה: אם תדפיס את הספציפיקציה האחרונה של ECMA תקבל 1308 דפי A4).
  3. כולם רצים לממש את מה שגוף התקינה הראשי אמר, נוצרים הרבה מנועים בשוק.

(זה לא בדיוק עובד ככה ולרוב המנועים בשוק מממשים דברים עוד לפני שהם נכנסו לתקן הרשמי ויאדה יאדה, אבל הבנתם את הרעיון הכללי).

בפייתון זה עובד קצת אחרת וטיפה יותר מבולגן:

  1. המימוש הרשמי הוא CPython. מה שקורה ב־CPython זה מה שאמור לקרות דה־יורה והתקן מוגדר ע"י מסמכי התיעוד של השפה, פחות או יותר.
  2. יש מסמכים שנקראים PEP, שהם קיצור ל־Python Enhancement Proposal. כשמם כן הם, הצעות לשיפור פייתון. כל תקופה יש אחד כזה שעושה הרבה מאוד רעש. המסמכים האלו הם חלק מהתקינה של פייתון.
  3. עד לפני שנה בערך היה לפייתון BDFL (Benevolent dictator for life) בשם Guido Van Russom. בפועל כל דבר שהיה רוצה להיכנס לפייתון היה צריך לעבור את אישורו, וככה השפה התנהלה במשך 3 העשורים האחרונים. לפני שנה לגוידו קצת נמאס (יש סיפור פוליטי עסיסי מאחורה, אבל נשאיר לפעם אחרת) והוא החליט שהוא פורש מהתפקיד. כך נוצרה Python steering council שמקבלת כיום את ההחלטות על השפה, ותפקידה מתוקנן לפי PEP 13.

לכל המימושים שרוצים שיהיה להם קהל משתמשים גדול יש אינטרס מאוד משמעותי לעמוד בתקן דה־פקטו, כדי שהמעבר של ארגונים ומשתמשים קיימים מ־CPython אליהם יעבור חלק.
נראה לי שזה מסכם את הנושא על רגל אחת :slight_smile:


בונוס: תמונה של Guido ועוד נספח משונה בכנס באורגון ב־2017 :slight_smile:

8 לייקים

המון תודות על התשובה המושקעת!