המקרה המוזר של טעינת ספריות מערכת ב Python

28/11/2016

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

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

1. הקוד שנכשל

נסו להפעיל את הקובץ demo.py בקונסולה הבאה ולאחר מכן הסתכלו בקוד המקור שלו כדי לאתר את השגיאה. הקוד צריך להדפיס מספר אקראי אבל במקום פשוט כותב bye bye ויוצא מיד:

2. מה קרה שם

מבט מהיר ברשימת הקבצים בתיקיה רומז על הבעיה. הקובץ demo.py טוען את המודול random, וזה בתורו טוען את המודול hashlib. הבעיה שבמקרה יש כבר תוכנית אחרת בתיקיה ששמה hashlib ולכן פייתון מתבלבל וטוען אותה במקום את מודול המערכת באותו השם.

מה שמבלבל כאן זה שבקוד שלי אין התיחסות למודול hashlib אלא רק למודול random. בשביל להבין ש hashlib אכן מפריע צריך או להכיר את שמות כל המודולים של המערכת, או להסתכל בקוד המודול random ולראות מה הוא טוען. אגב גם לא יעזור להריץ את הקובץ מתיקיה אחרת כי פייתון מחפש את hashlib באותה תיקיה בה נמצא demo.py.

3. איך זה לעומת שפות אחרות

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

ב perl התיקיה הנוכחית נמצאת ברשימת התיקיות לחיפוש מודולים אך היא האחרונה כך שמודול מהתיקיה הנוכחית שיש לו אותו שם כמו מודול מערכת לעולם לא יקבל עדיפות. בנוסף סיומת ברירת המחדל למודולים בפרל היא pm בעוד שסיומת תוכניות רגילות היא pl כך שהסיכוי לבילבול יורד שוב.

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

require './local-hashlib'

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