פייתון/פייתון גרסה 3/פונקציות המתכנת
הגדרה
עריכהפונקציה בדומה לפונקציה במתמטיקה היא פקודה באמצעותה מערכת הקוד של פייתון יודעת לייצא ערכים מתאים בהתאם ליחס שנקבעו מראש. חשוב לציין כי לא נוכל להריץ פונקציות ב-idle ולכן יש להכנס לסביבת עבודה אינטראקטיבית
לדוגמה, עבור כל היא תוכל למצוא את ערך ה- המתאים לו לפי ההגדרה אותה נקליד.
אם הפונקציה הוגדרה כמבטא יחס של והמשתמש ייקליד לתוכנה היא תייצא לו את הפלט .
מדוע צריך פונקציה?
עריכהכאשר יש שימוש בלולאות רבות העדפה היא להכניס כל איטרציה אל תוך פונקציה בפני עצמה.
היתרון בשימוש בפונקציה הוא החסכון במקום ושמירה על סדר.
במקום לרשום מחדש את הפקודות שנרצה שהמערכת תבצע שוב מחדש, נוכל לשמור אותם בתוך פונקציה לה נקרא בכל פעם כשנרצה.
בעיות ברצף קטן של פקודות קל יותר למעקב מאשר לולאה ארוכה או רצף פקודות אינסופי.
על כן אורכן של פונקציות לרוב לא עולה על יותר משבע שורות וכל פונקציה מגדירה יישום של פעולה יחידה.
איך כותבים פונקציה?
עריכהכל פונקציה נפתחת בהוראה def, שם הפונקציה, סוגרים ונקודתיים.
לאחר הסוגרים יורדים שורה ומזיחים את הפקודות בארבעה רווחים (whitespace). כל הזחה נקראת רמה (level).
הפונקציה מסתיימת בפקודת return. [1]
def <name>(<parameters >):
'''documentation'''
<Statements>
return
מבנה הפונקציה
עריכה- name הוא שם הפונקציה אותה מקליד המשתמש. מערכת פיתון אינה יודעת לזהות רווח ועל כן אם נרצה לתת שם ארוך ממילה אחת נעזר בקו תחתון (_)
- documentation הוא תיעוד של הפונקציה.
- Statements הם רצף של פקודות רצופות אותם מקליד המשתמש. במידה ותרצו לדלג על כתיבת הפונקציה תוחלפו להעזר ב-pass.
- arguments הוא ביטוי אותו מקליד המשתמש וגורם לפונקציה לפעול. למשל, אחת הפונקציות הראשונות שהכרנו הייתה type, באמצעותה יכולה המשתמש לדעת מה הטיפוס אותו הוא מקליד במערכת.
<<<type ('I love you')
<<class ‘str’>
- המחרוזת "I love you" היא הארגומנט של הפונקציה באמצעותה המערכת מתחילה לפעול. ניתן לייבא ארגומנטים גם דרך ה-#שורת הפקודות
- פרמטר הוא סוג של ארגומנט
לקרוא לפונקציה
עריכהלאחר שנכתוב את הפונקציה נרצה לקרוא לה (function call), דהינו, להשתמש בה. לשם כך נקליד את שם הפונקציה ואחריו סוגרים מסולסלים name()
.
נקליד את הפונקציה שבכל פעם שקוראים לה מקלידה את המחרוזת "hello world! I love you"
הפונקציה צריכה להראות כך:
def hello_world ():
print('hello world! I love you!')
return
בכדי לקרוא לה נקליד את הקלט:
>>>hello_world()
hello world! I love you!
לקרוא למיקום הפונקציה בזכרון:
print(hello_world)
>>><function hello_world at 0x03B1BAE0>
נשם לב שקריאה לפונקציה עצמה מחזירה את מיקומה בזכרון.
פרמטרים
עריכהפרמטרים (Parameters) - מציין אלו ארגומנטים המערכת יכולה לקבל מהמשתמש. כאשר אותם ארגומנטים מוקלדים מתרחשת הפעלת הפונקציה. רשימה זו יכולה להיות ריקה. לפני הפרמטרים ניתן להציב פונקציות
def solve(a,b):
return 2*a+5*b
>>> solve(5,6)
40
>>>print(x)
- בדוגמה זו שני פרמטרים מפעילים את הפונקציה.
ברירת מחדל של פרמטרים (parameters default value)
עריכהניתן להגדיר שאם פרמטר אינו מוקלד תבחר הפונקציה מספר אותו הגדיר המתכנת כברירת מחדל, המוגדר על ידי שיוויון (ראה את הפרמטר area).
def area_triangle(a, b, area=2):
print(a*b *(1/area))
>>> area_triangle(4,5)
10.0
>>> area_triangle(4,5,6)
3.333333333333333
- במקרה השני הפונקציה לא השתמש בברירת המחדל אלא בפרמטר אותו בחר המשתמש.
נהוג להציב את הפונקציות בראשית רצף הפקודות ואחריה יתר הפקודות.
*args
עריכהכאשר אנו לא יודעים כמה פרמטר יכניס המשתמש, למשל, מה הגילאים של הילדים של משתמש זה או אחר נעזר בכוכבית.
#the function is print a name and the numbers of kids the person has
def How_many(name, *kids_ages):
print(name)
print(kids_ages)
How_many('Dani', 2, 23,45,65)
Dani
(2, 23, 45, 65)
**kwargs
עריכהdef data_print(**data):
print (data)
data_print(name = 'Alon')
>>>{'name': 'Alon'}
שגיאות נפוצות
עריכהאחת הטעויות הנפוצות בתכנות היא קריאה לפוקציה עם טיפוסים של פרמטרים שאינם מתאים לפונקציה.
נשם לב שפונקציה מטבעה אינה יודעת מה טיפוס של הפרמטר אותו מכניסים אליה. מבחינתה כל טיפוס יכול להיות פרמטר אך לא בהכרח שרצף הפקודות בתוכה יתאים לכל טיפוס של פרמטר וזו אחת הסיבות שחשוב לרשום ב - documentation הסבר על כל פרמטר אותו מקבלת הפונקציה וטיפוסו.
def multiplication(str1, str2):
return str1 * str2
print(multiplication(1, 2))
print(multiplication('ab', 'cd'))
>>>2
>>>Traceback (most recent call last):
File "C:\Users\user\Downloads\de\a.py", line 9, in <module>
print(multiplication('ab', 'cd'))
File "C:\Users\user\Downloads\de\a.py", line 5, in multiplication
return str1 * str2
TypeError: can't multiply sequence by non-int of type 'str'
return
עריכההפונקציה מסתיימת אחר המילה return גם אם קיימות אחריה מילים נוספות.
החזרת ערך חזרה יחיד
עריכהdef square(x):
return x*x
>>> square(5)
25
החזרת שני ערך חזרה
עריכההחזרת שני ערך חזרה מתבצע באמצעות פסיקים:
x=0
def square(x):
return x*x, 3*x
>>> square(4)
(16, 12)
פעולות אחרי return
עריכהכל פעולה אחרי ה-return היא חסרת משמעות אלא אם ערך ההחזרה נמצא בתנאים ואינו מסיים את פעולת הפונקציה:
def name_Alex():
return 'Alex'
print('Dana')
ערך החזרה
עריכהפונקציות ללא return מחזירות ערך none שאינו מודפס וערכו הבוליאני הוא שקר.
פונקציה עם retun מחזירות "ערך חזרה" (return value) בו ניתן להשתמש עבור ערכים אחרים.
def minute(second=1):
return second / 60
print('value return', minute())
def hours(how_many_hours):
return how_many_hours / 60
print('minutes in an hour : ' + str(hours(minute())))
נבצע הפעלה:
value return 0.016666666666666666
minutes in an hour : 0.0002777777777777778
הפונקציה שניות (minute) יכולה להריץ עצמה באמצעות ברירת המחדל ומייצרת ערך החזרה 0.166.
הפונקציה השניה מקבלת את ערך החזרה ומתחילה עם ערך זה כאילו היה הפרמטר שלה לפיכך היא מחלק את ערך החזרה שנוצר ב-60 וכך מתקבלת התוצאה לעיל.
ערך החזרה None
עריכהnone הוא ערך מיוחד אשר משמש להציג ערך אבסולוטי. כאמור כל פונקציה שאינה מחזירה ערך חזרה, מחזירה את ערך ה-none כאשר היא אינה מדפיסה אותו.
def hello_world():
print('hello_world')
x = hello_world()
print(x)
hello_world
None
המשתנה x מפעיל את הפונקציה שלנו hello world. נאחר שהיא ללא ערך חזרה מדפיס לנו פיתון שלפונקציה hello_world אין ערך (none).
ערך ההחזרה None הוא ביטוי שמור במערכת בו ניתן להשתמש במידה כערך החזרה, לדוגמה, כאשר תנאים מסוים מתרחשים.
תיעוד
עריכהdocumentation הוא תיעוד של הפונקציה. התיעוד הוא מקטע המזוהה על ידי הפונקציה help והוא סוג של חוזה שמפרט מה הפונקציה מבטיח ואילו תנאים דורשת. על כן התיעוד כולל:
- תיאור הפונקציה
- פרטים על הפרמטרים והתנאים - מה הטיפוס של הפרמטרים, תחום הערכים שהם מקבלים (לדוגמה אם הפונקציה היא לולאת for עם range אזי range יכול לקבל רק פרמטרים חיובים ולכן נציין זאת).
- אילו טיפוסים מחזירה הפונקציה והתנאים שהם מקיימים.
לאחר הגדרת הפונקציה והפרמטרים אותם היא מקבלת, ניתן לרשום בפנים הפונקציה ולאחריהם רווח, ולקבל את המבנה הסטנדרטי ששמור במערכת עבור הערכים של הפונקציה שלנו אותם עלינו למלא בכדי להגדיר את הפונקציה כהלכה.
אם במהלך התיעוד הפונקציה משנה רשימה (או טיפוס שניתן לשנותו) לרשימה אחרת יש לרשום זאת בתיעוד הפונקציה. בדוגמה הבא מטרת הפונקציה לשנות את הרשימה אך במקרים רבות זהו שלב אחד בהגדרת הפונקציה:
def zero_lst(lst):
lst[0]=0
list_1=[1,2,3]
zero_lst(list_1)
print(list_1)
משתנים גלובליים, מקומיים
עריכההמשתנים והפרמטרים בפונקציה נקראים "משתנים מקומיים" (Local variables) לעומת הפרמטרים שנמצאים מחוץ לפונקציה ונקראים "משתנים גלובלים" (global). בעוד אנו יכולים לשנות את המשתנים המקומיים, לא נוכל לשנות את הערכים הגלובליים.
x=0
def square():
x=2
return 4*x+x
print(x)
הוא משתנה גלובלי. הוא משתנה של הפונקציה. בד"כ מקובל לתת שמות שונים לערך מקומי וגלובלי באותו רצף של פקודות.
כאמור, פרק משתנים, פייתון זוכרת את המשתנה האחרון שהוקלד בה:
y=0
def a():
y=1
print(y)
#print the vaule of the function:
a()
#print vaule y:
print('the vaule of y is: ', y)
>>>1
>>>the vaule of y is: 0
פייתון מזהה את המשתנה y המוגדר בתוך הפונקציה כאחד ולכן הדפיסה אחד. מחוץ לפונקציה, המשתנה y=0 ולכן ההדפסה עבורו היא 0.
טווח (scope) הוא התחום בו מוגדר המשתנה. יש לנו שני טווחים שונים עבור הערך y. אחד בתוך הפונקציה והשני מחוץ לו.
global
עריכהפונקציה ללא משתנה גלובלי תחזיר הודעת שגיאה:
counter = 1
def number():
for i in (1,2,3):
counter +=1
number()
print(counter)
>>>Traceback (most recent call last):
File "C:/Users/user/Downloads/de/t4.py", line 16, in <module>
number()
File "C:/Users/user/Downloads/de/t4.py", line 15, in number
counter +=1
UnboundLocalError: local variable 'counter' referenced before assignment
אם נרצה להגדיר את המשתנה שבפונקציה לפי המשתנה הגלובלי נוכל להעזר ב-global:
counter = 1
def number():
global counter
for i in (1,2,3):
counter +=1
number()
print(counter)
>>>4
הפונקציה global מקבלת את המשתנה הגלובלי ומפעילה אותו בפונקציה. נשם לב כי המשתנה הגלובלי שנה את ערכו!
הערכים של פונקציה
עריכהנבחן את הערכים שמחזירה פונקציה:
def exm (a,b):
return (a, b)
print(type(exm))
print(type(exm(2, 3)))
def number (a):
return (a)
print(type(exm))
print(type(exm(2, 3)))
print(type(number(2)))
<class 'function'>
<class 'tuple'>
<class 'function'>
<class 'tuple'>
<class 'int'>
כלומר הערכים תלויים בפרמטר אותם נציב אל הפונקציה
פונקציה מקוננת
עריכהקיימות פונקציות מקוננות במערכת ומוגרת לבצע פעולות שונות במערכת כמו פונקצית . רשימה מלאה: רשימת פונקציות מערכת built-in
- ^ כיום לא חייב לרשום את הפקודה מפני שתכנת רבות משלימות פקודה זו ועדין מקובל למען הסדר הטוב לציין אותה