top of page

רעננו את הדף והקליקו למעבר לנושא הבא:

with – מנהל הקשר (context manager)

  • Feb 2, 2019
  • 2 min read

with – מנהל הקשר (context manager)

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

בואו נראה קודם את הדרך הישנה ואז את הדרך עם with –

# הדרך הישנה

f = open("myfile.txt", "w")

f.write("שלום עולם")

f.close()

# הדרך עם with

with open("myfile.txt", "w") as f:

f.write("שלום עולם")

בגרסה עם with, הקובץ נסגר אוטומטית ברגע שיוצאים מהבלוק – גם אם קרתה שגיאה באמצע. אין צורך לקרוא ל-close בעצמנו. המילה as נותנת לנו שם למשתנה שמייצג את הקובץ הפתוח.

למה זה חשוב? בגלל שגיאות. תראו מה קורה בלי with –

f = open("data.txt", "r") content = f.read() result = int(content) # שגיאה אם הקובץ לא מכיל מספר! f.close() # השורה הזו לא תתבצע אם יש שגיאה למעלה

אם השורה השלישית זורקת שגיאה, close לעולם לא ייקרא והקובץ יישאר פתוח. עם with הבעיה הזאת לא קיימת –

with open("data.txt", "r") as f: content = f.read() result = int(content) # גם אם יש שגיאה כאן # הקובץ נסגר אוטומטית, תמיד

אפשר גם לפתוח כמה קבצים בו-זמנית –

with open("input.txt", "r") as fin, open("output.txt", "w") as fout: for line in fin: fout.write(line.upper())

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

איך with עובד מאחורי הקלעים? כל אובייקט שתומך ב-with צריך לממש שתי מתודות מיוחדות – __enter__ ו-__exit__. המתודה __enter__ רצה כשנכנים לבלוק, ו-__exit__ רצה כשיוצאים ממנו (גם אם יצאנו בגלל שגיאה). בואו ניצור מנהל הקשר משלנו –

class Timer: def __enter__(self): import time self.start = time.time() print("מתחילים למדוד זמן...") return self def __exit__(self, exc_type, exc_val, exc_tb): import time elapsed = time.time() - self.start print(f"עברו {elapsed:.4f} שניות") return False

with Timer(): total = sum(range(1000000))

>>>

מתחילים למדוד זמן...

עברו 0.0312 שניות

יצרנו מחלקה Timer שמודדת כמה זמן עבר בתוך בלוק with. כש-with מתחיל, __enter__ שומר את הזמן הנוכחי. כש-with נגמר, __exit__ מחשב כמה זמן עבר ומדפיס. ה-return False ב-__exit__ אומר שאם הייתה שגיאה, שתמשיך להתפשט (אם היינו מחזירים True היא הייתה נבלעת).

אפשר ליצור מנהלי הקשר גם בדרך קצרה יותר עם הדקורטור contextmanager מספריית contextlib –

from contextlib import contextmanager @contextmanager def loud_block(name): print(f"נכנסים ל-{name}") yield print(f"יוצאים מ-{name}") with loud_block("חישוב"): print("עובדים...")

>>>

נכנסים ל-חישוב

עובדים...

יוצאים מ-חישוב

כל מה שלפני yield הוא ה-__enter__ וכל מה שאחרי yield הוא ה-__exit__. דרך קומפקטית ונוחה במיוחד למקרים פשוטים.

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

 
 
 

Related Posts

See All
תוכן הקורס

לחץ למעבר לשיעור תוכן עניינים מבוא הורדה והתקנת התוכנה על גבי המחשב שלכם חלק ראשון - יסודות פקודת print מחרוזות - גרשיים (") או גרש (') פעולות מתמטיות בסיסיות סוגי מספרים - integer

 
 
 
מבוא

הרקע של פייתון - שפת התכנות פייתון (python) פותחה על ידי הולנדי בשם Guido van Rossum ונקראה בהומור על שם חבורות הקומיקאים הבריטית מונטי-פייתון, כאשר משמעות המילה פייתון כשלעצמה היא נחש חנק מסוג פיתון,

 
 
 
הורדה והתקנת פייתון על גבי המחשב שלכם

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

 
 
 

Comments


Single Post: Blog_Single_Post_Widget
bottom of page