
isinstance ל-type. הרעיון של הדפוס הוא להפריד בין מה שצריך לבין איך מייצרים אותו.__new__ ו-__init__: __new__ יוצרת את האובייקט, ורק אחריה __init__ מאתחלת את השדות. לכן אפשר לדרוס את __new__ ולהחזיר אובייקט ממחלקה אחרת.Spring, Fall, Summer ו-Winter, ומחלקת SeasonFactory עם מילון סטטי שממפה מחרוזות למחלקות.winter מחזירה אובייקט מסוג Winter, ויצירה עם summer מחזירה Summer.isinstance בודקת אם האובייקט הוא מהמחלקה שציינו או ממחלקה שיורשת ממנה.type בודקת את הסוג המדויק בלבד. לכן אובייקט ממחלקה שיורשת מ-Summer יחזיר True ל-isinstance, אבל לא יהיה מסוג Summer ב-type.הטקסט המלא של הדקות הראשונות בהרצאה «פייטון design pattern factory» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
שלום לכולם, בשיעור הזה אנחנו נדבר על דיזיין פקטורי, דיזיין פאטרן זה שם פקטורי, איך ממשיכים אותו בפייתון בקלות.
דבר ראשון, נסביר בקצרה את הדיזיין פאטרן, מה המשמעות שלו. הדיזיין פאטרן פקטורי בא להפריד בין מה אני צריך לבין איך אני מייצר אותו. אם למשל ניתן דוגמה, בן אדם בא לחנות, בא למוכר, אומר לו, אני צריך בטטה, אני לא יודע איך נראית בטטה, לא יודע, אני רק יודע שאני, אשתי ביקשה ממני בטטה.
אז הוא אומר למוכר, והמוכר מביא לו בטטה. הוא יכול להגיד לו, תביא לי תפוח אדמה, הוא מביא לו תפוח אדמה. עכשיו, אם בעוד שנתיים יצא תפוח אדמה או בטטה יותר משוכללים, אני אבוא למוכר ואני אגיד לו, תביא לי תפוח אדמה.
הוא יביא לי כבר את התפוח אדמה יותר חדש. ועכשיו, במעבר לתכנות, איך זה עובד פה? אני יודע שאני צריך קלאס מסוים, מסוג מסוים. אני בא לפקטורי, אני אומר לו, אני יודע שאני צריך קלאס מסוג A, אבל תביא לי בתכלס, ואתה תדאג להביא לי את A איך שצריך.
אני לא יודע איך לייצר את A, אני רק יודע שאני צריך A כדי לעבוד. אתה תביא לי את A. בואו עכשיו נראה איך הדבר הזה קורה בפייתון.
לפני כן, רק נגיד משהו. חדי העין מביניכם בטח שמתם לב שהפונקציה של פייתון שיוצרת, כל הפונקציות של הקונסטרקטור שדיברנו עליהם עד עכשיו, קוראו להם איניט.
כלומר, פונקציות אתחול, לא קריאייט. כלומר, הפונקציית איניט היא מקבלת כבר סלף מוכן והיא מאתחלת אותו בשדות.
אבל לא דיברנו עדיין על מי יוצר את הסלף הזה, מאיפה הוא מגיע. אז הסלף הזה מגיע מפונקציה שנקראת ניו. הפונקציה ניו מקבלת את הטייפ של הקלאס ואת שאר הפרמטרים שמתגלגלים מהאיניט, והפונקציה new יוצרת את האינסטנס של הקלאס ואז היא מתגלגל לפונקציה init שהיא מאתחלת אותו, היא עושה לו initialize בשדות.
כלומר, כשאני קורא ל... אם נחזור רגע לדוגמה הקודמת, כשאני קורא ל person, אני בעצם קורא לפונקציה new, היא יוצרת לי את ה-self, היא לאחר מכן נקראת הפונקציה init עם ה-self שנוצר לי ב-new והיא נתמהתחלת אותו בערכים שקראתי להם בפונקציה.
עכשיו אנחנו נדרוס את הפונקציה new ונראה איך עושים את זה בצורה חכמה. אז קודם כל נדבר מה יש לנו פה. אז יש לנו פה ארבע קלאסים ריקים, בעזרת המילה pass, בעצם המילה pass מאפשרת לי להשאיר את הקלאס ריק בלי למלא אותו בשום תוכן.
אז אני יצרתי פה ארבע קלאסים שמייצגים את עונות השנה, Spring, Fall, Summer ו-Winter ויצרתי עוד קלאס שהוא הפקטורי שלי, Season Factory.
וב-Season Factory יצרתי Static Member שנקרא Season, שהוא מכיל Dictionary שבו ה-Stringים מסוימים מצביעים לי על שם של קלאס מסוים.
וכשקוראים לפונקציה New, מה שקורה, אני קורא ל-Seasons שנמצא בתוך Season Factory, במקום ה-Season, זה המשתנה שקיבלתי בפונקציה new, ואני קורא לקונסטרקטור שלו.
זאת קריאה לפונקציה. עכשיו בוא נפעיל את הדבר הזה ונראה את הקלט וננסה להבין מה קרה פה. אני בעצם יצרתי season factory, בעצם באתי למוכר בחנות, אמרתי תביא לי חורף, באתי ל-season factory ואמרתי לו תביא לי winter.
עכשיו מי שקורא את הקוד הזה ולא רואה בעצם את כל הקוד הזה, שסיזן פקטורי, אם אני אעשה לו טייפ, שטייפ מדפיסה את מה שיש לי ביד, אז אנחנו נקבל טייפ סיזן פקטורי.
בפועל, אנחנו רואים שקיבלנו טייפ וינטר. למה זה קרה? כשקראנו ל-new, במקום שהיא תחזיר את ה-self של סיזן פקטורי, היא החזירה self אחר, היא קראה פה ל-constructor של במקרה הזה וינטר, ווינטר נכנס לפה לסיזן והחזיר לנו את הקלאס ווינטר ואנחנו קוראים פה לקונסטרקטור של ווינטר
ובסופו של דבר מתגלגל לנו החוצה מתוך ה-new ומתוך ה-init אובייקט מסוג ווינטר. זאת אומרת שיש לנו פה דיזיין פאטר של פקטורי ממש בקלות. על ידי קריאה, על ידי overriding על הפונקציה new אנחנו הצלחנו לעשות פה פקטורי ממש בקלות.
זה היה לנו ממש פשוט, בואו עכשיו נראה דוגמה שאנחנו קוראים לסאמר אז בואו נגיד s שווה ל-seasonFactory והפעם נביא לו סאמר