10 תשובות
זה תלוי

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

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

callable - פונקצייה שמחזירה true אם ניתן לקרוא אל אובייקט (כלומר שהמחלקה אליה הוא שייך יש שיטת __call__. אם האובייקט הוא מחלקה ולא מופע שלה, אז הוא בהכרח ניתן לקריאה), אחרת מחזירה false. הפונקצייה נשמעת לא שימושית, אבל היא דווקא מאוד שימושית מהסיבה שאחד הבאגים בפייתון הוא קריאה לאובייקט שלא ניתן לקריאה. אני אדגים את זה. בוא נניח שאתה כותב את שורת הקוד הבאה:
5()
אתה הולך לקבל ממנה באג שכולל את ההודעה הבאה:
<string>:1: syntaxwarning: 'int' object is not callable; perhaps you missed a comma?
traceback (most recent call last):
file "<string>", line 1, in <module>
typeerror: 'int' object is not callable

אז מה זה אומר לנו? זה נותן לנו אזהרת תחביר על כך שאובייקטים מטיפוס int או מופעים של המחלקה int (איך שתרצה לנסח את זה, זה לא באמת משנה) אינם ניתנים לקריאה. לאחר מכן מגיע הtraceback שמציין באיזה חלק של הקוד השגיאה אירעה (מסתבר שזה קרה בתוך חלק של מחרוזת, למרות שלא השתמשתי בשום מחרוזת. חוץ מזה, זה גם יכול לכתוב חלקים אחרים כמו בתוך list comprehension ואז יכתוב לנו listcomp), ואפילו באיזה שורה, וגם באיזה מודול (במקרה שלנו זה המודול הסטנדרטי) ואז זה זה כותב typeerror שזה שגיאה שמגיעה מלהשתמש בפרמטר, בארגומנט או באופרנד שהטיפוס נתונים שלהם אינו מאפשר להשתמש בפונקצייה, שיטה או אופרטור כלשהו. במקרה שלנו זה שהשתמשנו בקריאה למרות שלאובייקט שלנו לא היה שיטת __call__ במחלקה שהוא משתייך אליה. זה עוד קל לפתירה, אבל זה הרבה יקרה לך שאתה תקרא בטעות לאובייקט בלתי קריא, וזו בעיה גדולה. אז עכשיו בוא תסתכל על איך משתמשים בפונקציה ואיך היא פותרת את הבעיה:
ניקח את שורת הקוד הבאה:
print(callable(5))

אז יודפס לי הערך false. למה? כי למחלקה int (שאליה 5 משתייך) אין את מתודת __call__

עכשיו ניקח את הדוגמה הזאת:

print(callable(bin))

אז יודפס לי הערך true. למה? כי למחלקה של bin שנקראת builtin_function_or_method יש את השיטה __call__

עכשיו זה יותר ברור? אני מקווה שאתה תוכל להשתמש בזה אחר כך. אבל יש דרכים גם לבדוק את בלי הפונקציה callable.

#דרך 1

def iscallable(x):
try:
x.__call__
return true
except:
return false
print(iscallable(5))
print(iscallable(bin))

סקרינשוט בשביל אינדטציה ברורה:

http://www.up2me.co.il/v.php?file=80137111.jpg

#דרך 2

iscallable=lambda x:true if'__call__'in dir(x)else false

print(iscallable(5))
print(iscallable(bin))

#דרך 3

iscallable=lambda x:hasattr(x,'__call__')

print(iscallable(5))
print(iscallable(bin))

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

אני אמליץ ללמוד על lambda, זו דרך נחמדה לקצר קוד
שואל השאלה:
וואה וואה תודה על ההשקעה
אנונימי
אנונימי, תודה רבה!

עכשיו ההסבר על הדרכים (בכל הדרכים אני מגדירה פונקצייה בשם sum עם פרמטר בשם x, מציינת מראש בשביל לא לציין את זה 3 פעמים):
דרך א:
בדרך א אני משתמשת בtry except שזה בלוקים בפייתון במבנה שבו try הוא קוד שאני מריצה, אבל אם יש באג באמצע, אז הexcept מתחיל לפעול. אני יכולתי לעשות בלוק מלא של זה שזה try except finally else אבל זה מיותר פה לחלוטין.

אז פה שמתי בתוך הבלוק try את הקוד:
x.__call__
return true

ובתוך הexcept שמתי return false

אז מה זה אומר? בוא נתחיל בניתוח.

לגבי הבלוק try, מה שאני עושה בו זה כותבת את x ומציינת את הattribute שלו שבמקרה הזה הוא __call__ (הערה: אני לא קוראת אל הפונקצייה). בשורה הבאה אני כתבתי return true שזה אומר לתוכנה להחזיר את הקבוע הבוליאני true (הוא נועד לייצג ערך שהוא נכון). אחר כך יש את הבלוק except שרץ אם היה באג בבלוק הקודם (שהוא try) שבו אני כותבת לתוכנה להחזיר את הקבוע הבוליאני false (הוא נועד לייצג ערך לא נכון)

עכשיו למה אני עושה את זה? זה כי הבאג שיכול לעלות פה הוא אם אני משתמשת בattribute שאין לאובייקט (שם הבאג הוא attributeerror). אז מה שאני עושה למעשה זה בודקת האם יש לx את הattribute בשם __call__ (כן, גם שיטות של אובייקט הן attribute שלו) בכך שאני כותבת את השורת קוד הזו, אבל טכנית היא לא עושה כלום כי אני לא קוראת אל הפונקציה. אבל בגלל שלא בהכרח יש לx את הattribute בשם __call__ אז גם לא בהכרח נישאר בבלוק הtry אלא נעבור לexcept

עכשיו אם הכל הולך חלק אז יוחזר true כי באמת כתבתי את הattribute של x ואכן יש לx את הattribute אז זה עובר לשורה הבאה ומחזיר true. אבל מה לגבי המקרה שבו אין את הattribute בשם __call__ לx? אז יועלה הבאג attributeerror שמגיע מסיבות שהוזכרו והוסברו לפני כן, אבל בגלל שאנחנו בתוך בלוקים של try except אז זה אוטומטית יקפוץ לבלוק הexcept ושם הוא הולך להחזיר false.

כמו בפונקציה callable, זה יחזיר true כשיש את השיטה (שהיא גם attribute כפי שציינתי והסברתי לפני) __call__ לארגומנט (ארגומנט זה אובייקט שמשמש כהצבה של פרמטר של פונקציה או שיטה) אחרת יחזיר false.

דרך ב:

אני בודקת שם בפונקציית למדא לגבי האם יש את המחרוזת '__call__' בתוך הdir של הפרמטר x, אם יש אז יוחזר true אחרת false

הסיבה היא כזאת: dir זו פונקצייה שמחזירה את כל הattributes של אובייקט. זה הסבר בפשטות עליה כי היא קצת יותר מורכבת. היא מחזירה אותם בתור מחרוזת. לכן אני בודקת על זה בתור מחרוזת. אם יש מחרוזת כלשהי בתוך הרשימת dir אז מה שבתוך הגרשיים/המרכאות זה attribute של אותו ארגומנט שהצבנו. לכן, אני בודקת האם יש את המחרוזת הזו ברשימת הdir, בשביל לדעת שיש את הattribute הזה לפרמטר x

דרך ג:

אין כמעט מה להסביר על דרך ג, אני פשוט קוראת אל הפונקצייה hasattr

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

האמת שלא הכרתי את הפונקציה dir ובמקום להשתמש בbin השתמשתי בint(x,2).
הפונקציה int יכולה גם להמיר לבסיסים ולא הרבה מתכנתים יודעים את זה.
בתכנות היי לבל כמו בפייתון לא צריך להשתמש הרבה בבינארית אבל זה עדיין שימושי מדי פעם
אה יפה שלמדת משהו, הכרת את hasattr לפני או לא?

דרך אגב, הכרתי ממש לאחרונה שיש אפשרות בint להמיר בסיסים, זו אפשרות מאוד נחמדה לפי דעתי
הכרתי את hasattr אבל אף פעם לא יצא לי להשתמש בזה :)
איך? אתה דווקא די צריך

אבל למקרה ששואל השאלה קורא את זה אז אסביר גם על hasattr

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

הסבר א:
מה שבתוך הגרשיים של המחרוזת הוא נבדק אם הוא אכן attribute של הפרמטר הראשון. אם הוא כן, מוחזר true, אחרת יוחזר false

הסבר ב:
הבלוקים של try ו-except נבדק אם ניתן לקרוא לפונקציה getattr תוך שמציבים אותם פרמטרים כמו אלו שדיברתי לפני (אובייקט והמחרוזת שמייצגת attribute) ואם הניסיון אכן מוצלח יוחזר true, אחרת יוחזר false
חחח לא יודע, פשוט לא יצא לי לעשות משהו שדרש את זה