פייתון/פייתון גרסה 2/גרסה להדפסה
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
הקדמה
[עריכה]פייתון היא שפת סקריפט המפותחת בקוד פתוח. זו שפה מודרנית מאוד: מונחית עצמים, בעלת יכולת תכנות פונקציונלי, ועוד. פייתון מתאימה למגוון מטלות תכנות, החל מכתיבת קובץ אצווה פשוט, וכלה באפליקציות מדעיות מתוחכמות. פייתון רצה על מערכות לינוקס, חלונות ומקינטוש. שפה זו קיבלה את שמה בהשראת הקרקס המעופף של מונטי פייתון (וזו אינה בדיחה).
פייתון נבנתה בדגש על קריאוּת והקטנת מאמצי המתכנת, ולכן אינה יכולה להתחרות כלל בביצועי המהירות של שפות גנמוכות יותר, כשפת C. עם זאת, פייתון גם מתאימה לתחומים עתירי ביצועים. קל מאד להרחיב את השפה בעזרת כתיבת מודולים בשפת C או בC++. התחביר הנוח של השפה הופך אותה למצויינת כשפת דבק המחברת בין מודולים יעילים הכתובים בשפות נמוכות יותר.
איזה ידע קודם נדרש?
[עריכה]- נסיון בסיסי בעבודה עם מחשבים נדרש, שכן להפעלת תוכנות בשפה יש להשתמש במחשב.
- הכרת אנגלית יכולה לסייע מאוד, שכן השפה משתמשת באנגלית, ורוב התיעוד של השפה הוא בשפה האנגלית. כמו כן, אחת החוזקות של פייתון היא קהילת המשתמשים שלה - ולצורך תקשורת עם קהילה זו נדרשת יכולת תקשורת באנגלית.
אין צורך בהכרה מוקדמת של השפה או של שפות תכנות אחרות - הספר מלמד את עקרונותיה החל מהבסיס.
לקריאה נוספת
[עריכה]- Chun, W. J., Core Python programming, Prentice Hall, Upper Saddle River, N.J., 2007
- Langtangen, H. P., Python scripting for computational science, Springer, Berlin, 2006
- Brown, M. C., Python :the complete reference, Osborne/McGraw-Hill, New-York, 2001
- Beazley, D. M., Python essential reference, New Riders, Indianapolis, Ind., 2000
קישורים חיצוניים
[עריכה]- אתר הבית
- התיעוד של פייתון
- אתר עברי ללימוד פייתון
- Python-IL - אתר קהילת הפייתון הישראלית
הכנה
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
הרכיבים הנדרשים לפיתוח בפייתון
[עריכה]כדי לפתח בפייתון, יש להשתמש במספר רכיבים שיפורטו להלן.
עורך טקסטים
[עריכה]כדי לכתוב תוכניות פייתון, ראשית, יש להשתמש בעורך טקסטים כדי לכתוב את הקוד. חשוב להשתמש בתכנה המאפשרת לשמור קבצי טקסט פשוטים (ללא סימני עריכה כלשהם). להלן מספר עורכי טקסט המתאימים לפיתוח. חלקם תומך בתכונות כמו highlighting, יישור אוטומטי, סימון פיסקאות, השלמה אוטומטית של מילים, ועוד. ראוי לציין כי עורכי הטקסט שמוצגים כאן אינם מוגבלים לתמיכה בשפה זו או אחרת, אלא מתאימים למגוון רחב של שפות תכנות שונות.
לינוקס
[עריכה]- מספר עורכים מגיעים כחלק אינטגרלי משולחנות העבודה השונים:
- מספר עורכי טקסט נפוצים מאד, אך מתאפיינים בממשק מסובך או טקסטואלי, היכול להקשות על מי שלא התרגל אליהם:
- Emacs - עורך טקסט משוכלל, המציג רשימה ארוכה מאוד של תכונות, ותמיכה במגוון של אפשרויות עבודה. הוא דורש זמן לימוד מסויים, מכיוון שהממשק שלו מעט שונה משל מרבית הממשקים המוכרים.
- vi, Vim - משוכלל וניתן להרחבה, מתחרה וותיק של emacs. מתאפיין גם כן בממשק רב אפשרויות הדורש לימוד.
- nano - עורך זעיר בעל מימשק טקסטואלי לחלוטין.
- Eclipse - סביבת עבודה נפוצה ל-Java. ניתן לתכנות ב-Python דרך ההרחבה "PyDev".
ניתן להתקין את כל העורכים הנ"ל בעזרת מנהלי החבילות המתאימים.
OSX
[עריכה]פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
חלונות
[עריכה]- ++Notepad עורך טקסט פשוט התומך בhighlighting לשפות רבות.
- פנקס רשימות - עורך טקסט פשוט שמגיע עם כל התקנה של חלונות.
המפרש
[עריכה]המְפָרֵשׁ (interpreter בלעז) ממיר את הקוד הכתוב לשפת מכונה ומבצע אותה. פייתון, כרוב שפות התכנות, מוגדרת בעזרת כללים נוקשים למדי. במידה שהקוד מכיל "שגיאות דקדוק" (כלומר, שהקוד אינו כתוב לפי כללי השפה), המתרגם יודיע על שגיאות.
תוכל להוריד מפרש פייתון חופשי מכאן. בלינוקס (במקרה שפייתון אינה מותקנת) כדאי להשתמש במנהלי החבילות המתאימים.
הספרייה הסטנדרטית
[עריכה]פייתון כוללת ספרייה סטנדרטית אדירת מימדים, המכילה מגוון רחב של קוד מוכן לשימוש. ספריה זו מותקנת בדרך כלל כאשר מתקינים את המתרגם, ולכן אין צורך בדרך כלל בהתקנתה בנפרד.
סביבות פיתוח
[עריכה]יש המעדיפים לעבוד בשילוב של הרכיבים שבהם כבר דנו: למצוא עורך טקסטים המתאים להם, מתרגם כזה או אחר, וכולי. מאידך, ישנן תוכנות הנקראות סביבות פיתוח, המאגדות כבר את הרכיבים הנדרשים לפיתוח, ויש המעדיפים להשתמש בהן. אתר הבית של פייתון מפרט תוכנות כאלו. חלקן יפורטו כאן:
חלונות
[עריכה]- ActivePython של חברת ActiveState (קיימת גרסה חינמית) - כולל התקנה קלה יחסית, עורך עם השלמות אוטומטיות, ויכולת פשוטה להרצה של קוד פייתון.
- Pythonxy גרסת קוד פתוח חינמית לחלוטין כולל התקנה קלה שמוכוונת להנדסה ומדעים עם ממשק spyder דמוי matlab
- IronPython - ישום .NET-י של שפת פייתון.
- Eclipse - סביבת עבודה נפוצה ל-Java. ניתן לתכנות ב-Python דרך ההרחבה "PyDev".
סביבות ריצה
[עריכה]קוד שנכתב בשפת פייתון ניתן להריץ במספר דרכים:
- על מחשבים עליהם מותקן המפרש של פייתון - ניתן באמצעות המפרש להריץ סקריפטים של פייתון (תוכנות פייתון).
- קיימים כלים להפיכת קוד פייתון לקבצים בינאריים הניתנים להרצה בסביבות שונות (למשל py2exe הופך קוד פייתון לקוד הניתן להרצה בסביבת חלונות).
- ניתן להריץ קוד פייתון על גבי שרתי ווב - כך modpython מאפשר הרצת קוד פייתון על גבי שרת Apache.
- Google App Engine - שירות של גוגל, במסגרתו ניתן להריץ קוד פייתון על שרתים מנוהלים של גוגל, בחינם (עד לגבול מסויים) וללא התחייבות. מדובר בסביבה שדואגת לפריסה והרצה של קוד פייתון על גבי שרתים בעולם, כדי לאפשר כתיבה פשוטה של Web Services ו Web Applications.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
IDLE
יצירת תוכניות והפעלתם
[עריכה]פיתחו את IDLE אם עדיין לא עשיתם זאת. בתפריט העליון, בחרו בקובץ File
ואז חלון חדש New Window
. בחלון החדש שמופיע, הקלדו בקשה להדפיס "שלום עולם" כלומר את השורה הבאה:
print "Hello, World"
כעת, שימרו את התוכנית: מתוך התפריט של קובץ File
בחרו שמור Save
, ולאחר מכן שימרו אותה בשם " hello.py
" (אתם יכולים לשמור אותה בכל תיקייה שתרצו). כעת, התוכנית שמורה וניתנת להרצה.
השלב הבא להריץ את התוכנית על ידי בחירה מהתפריט הפעלה Run
ואז הרצת התוכנית Run Module
. הפלט של התוכנית יהיה הדפסה של "שלום עולם" Hello, World
בתוך חלון ההרצה של פייתון *Python Shell*
ללימוד מעמיק יותר של IDLE, עם צילומי מסך ניתן למצוא בכתובת http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html
שמות התוכניות
[עריכה]כדאי לשמור על כמה כללים לגבי שמות הקבצים של תוכניות פייתון. אחרת דברים עלולים להשתבש באופן בלתי צפוי.
- תמיד לשמור את התוכנית עם הסיומת py. אין לשים נקודה נוספת במקום אחר בשם הקובץ.
- השתמשו רק בתווים רגילים בשמות הקובץ: אותיות, מספרים, מקף ( - ) וגם קו תחתון (_ ).
- אין להשתמש ברווח ( " ") אפשר להשתמש בקו תחתון במקום.
- השתמשו רק באותיות (במיוחד לא מספרים!) בתחילת שם קובץ.
- אל תשתמשו בתווים "שאינם באנגלית" כגון אותיות עבריות בשמות הקבצים, אפילו עדיף לא להשתמש בהם כלל גם בתוך התוכנית.
הרצת פייתון משורת הפקודה
[עריכה]כשלא רוצים להריץ את פייתון מ IDLE ניתן להכנס למצב אינטראקטיבי בהרצה משורת הפקודה פשוט הקלידו python
בלבד. כדי להריץ תוכנית, צרו אותה עם עורך טקסט (למשל emacs עובד טוב עם פייתון) ולאחר מכן הריצו את פייתון כששם התוכנית שלכם הינה המשתנה שהפייתון מקבל python program_name
.
בנוסף, כדי להשתמש בפייתון עם vim, מומלץ לבקר באתר: Using vim as a Python IDLE
שלום עולם!
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
נהוג לפתוח תיאור של שפת תכנות באמצעות הצגת תכנית פשוטה המדפיסה "שלום עולם!" למסך. בכך ניתן לראות את המבנה הבסיסי של שפת התכנות ואת הדרך שבה היא מבצעת הדפסות למסך. לא נחרוג ממנהג זה כאן.
שתי צורות העבודה בפייתון
[עריכה]בפייתון קיימות שתי צורות עבודה:
- אפשר לעבוד אינטראקטיבית במעטפת פקודה. לאחר הקלדת כל פקודה, מקבלים ישירות את תוצאת המתרגם. עליה נעבוד ונתרגל מאחר שאנחנו מנסים פקודות חדשות לנו.
- אפשר לשמור רצפי פקודות בקובץ אצווה, ולהריץ את המתרגם על הקובץ. צורת עבודה זו דומה יותר (אם כי לא זהה) למקובל בשפות מהודרות כשפת C.
לתשומת לבך: נתן לעבוד בעורך הטקסט ולשמור את הקובץ בסיומת py או pyw אבל צריך מריץ פייתון כמו בjava.
עבודה אינטראקטיבית
[עריכה]פתיחת IDLE
[עריכה]פתחו את IDLE (הממשק הגרפי של פייתון Python GUI). אם אינכם מוצאים אותו:
- פתחו טרמינל (חלון פקודות):
- בלינוקס, הקש Alt+F2 והקלד konsole אם הינך בסביבת KDE, או gnome-terminal אם הינך בסביבת GNOME.
- בחלונות, הקש Win+R והקלד cmd.
- במערכת חלונות, מצא היכן מותקנת פייתון במחשב שלך. לרוב, אם הנך משתמש בPython 2.7, תותקן התוכנה בC:\pyton27. הקלד set path=%path%;C:\python27 (או שם הספרייה במערכת שלך), והקש Enter.
- הקלד python, והקש Enter.
מסך המתרגם
[עריכה]כשהמתרגם עולה במצב אינטראקטיבי, הוא מדפיס ראשית הודעת ברכה המשתנה ממערכת אחת לשנייה.
Python 2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>>
הסימן <<<
נקרא prompt, והוא מסמן שהמתרגם ממתין לפקודה, דהינו שאנחנו במצב אינטרקטיבי.
עכשיו תורכם: נסו להקליד1+1 ופייתון יחזיר את התשובה 2 .
|
Hello, world
[עריכה]נקליד כעת את השורה הבאה, המסמנת שברצוננו להדפיס את 'Hello, world!':
>>> print 'Hello, world!'
כאשר נקיש Enter, המתרגם יבצע את הפקודה, וידפיס את התוצאה המבוקשת.
>>> print 'Hello, world!'
Hello, world!
>>>
לאחר ההדפסה, המתרגם ממתין לפקודה הבאה.
שימו לב: אם ברשותכם גרסה 3 ומעלה של פייתון יהיה עליכם לכם לכתוב:
>>> print('Hello, world!')
קובץ אצווה
[עריכה]ניתן לכתוב קובץ אצווה (סקריפט) על ידי עורך טקסט, ולהפעילו ללא כניסה ישירה לפייתון עצמה.
פתח עורך טקסטים, ורשום בו
#!/usr/bin/env python
print 'Hello, world!'
שמור את הקובץ בשם hello.py כקובץ טקסט (ללא סימני עריכה) בתיקיה בה יש לך הרשאות מתאימות.
פתח חלון טרמינל, ונווט לתיקיה בה שמרת את הקובץ. הקלד
python hello.py
או
hello.py .
והקש Enter.
המתרגם יזהה את פקודת ההדפסה, ובטרמינל תראה
Hello, world!
לחילופין ניתן לתת לקובץ הרשאות ריצה (בלינוקס) על ידי כתיבה חד-פעמית של:
chmod +x hello.py
ואז להריץ על ידי כתיבת:
./hello.py
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
תרגילים
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
שלום עולם! מותאם אישית
[עריכה]הפכי את הדוגמה הבסיסית לאישית יותר, על ידי הוספת שימך להדפסה. אם שמך ענת, לדוגמה, שני את הקוד כך שידפיס Hello World, Anat. בדקי שהנך מצליחה לערוך את השינויים במתרגם האינטראקטיבי.
>>>print 'Hello world, some1 who writes it!' בפייתון 3: >>>print("Hello world, Anat!")
הערות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
הערות בשפה אנושית (לרוב אנגלית) בקוד יכולות לשפר את בהירותו.
הערות שורה
[עריכה]הערות בפייתון מתחילות בתו # וממשיכות עד סוף השורה
# This is a comment.
המתרגם מתעלם מקטעים אלו, והם משמשים להסברת הקוד בלבד.
מקובל להתחיל כל תכנית בשם הקובץ, הסבר קצר על התכנית, שם המתכנת והתאריך.
השימוש בהערות
[עריכה]משתמשים בהערות כדי להבהיר את משמעותם של קטעי קוד שונים, או איך להשתמש בהם. בספר זה לעתים נשתמש בקטעי קוד כדי להסביר בתוך הקוד נקודות חדשות לגבי השפה. לדוגמה, בתוכנית שלום עולם! היינו יכולים להוסיף הערה בקוד, המסבירה היכן התוכנית מתחילה לרוץ:
# This line prints 'Hello, world!' to the screen.
print 'Hello, world!'
תיעוד פונקציות ומחלקות
[עריכה]
שקלו לדלג על נושא זה פסקה זו עוסקת בנושא מתקדם יותר הדורש ידע בפונקציות ובמחלקות. |
תיעוד קוד צריך להיות נגיש למפתח. לפייתון יש שתי מוסכמות בכתיבת תיעוד שכזה: האחד נוגע לפונקציות והשני למחלקות.
תיעוד פונקציה
[עריכה]את התיעוד יש למקם בראש הפונקציה (מתחת לכותרת) בין זוג גרשים משולשים:
def S(r):
'''This function returns the area of\na circle with radius r.'''
return 3.14*r*r
כעת ניתן לגשת לתיעוד זה באמצעות כתיבת:
>>> S.__doc__
'This function returns the area of\na circle with radius r.'
>>> print S.__doc__
This function returns the area of
a circle with radius r.
תיעוד מחלקה
[עריכה]תיעוד מחלקה מתבצע באמצעות כתיבת פונקציה פנימית מיוחדת בשם __doc__
:
class Blabla:
def __doc__(self):
intro_str = "This is a general purpose class for doing..."
doc_str = "The version of this class can be retrieved " +\
"by typing Blabla.version"
return intro_str + '\n' + doc_str
ניתן תמיד לגשת לתיעוד בשתי דרכים: ישירה (ע"י הדפסת המשתנה __doc__) ועקיפה (ע"י שימוש בפונקציה help הפנימית של פייתון).
הערות תיעוד מובנה ובדיקות תוכנה
[עריכה]
שקלו לדלג על נושא זה נושא זה חורג ברמתו והיקפו מספר זה. |
קיימת גם צורת הערות מתוחכמת יחסית, המשמשת לשימושים מתקדמים יותר:
קישורים חיצוניים
[עריכה]- ^ pydoc -- Documentation generator and online help system
- ^ doctest -- Test interactive Python examples
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מחרוזות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מחרוזת היא רצף של תווים, המשמשת בדרך כלל לביטוי מילים או משפטים.
הגדרת מחרוזת
[עריכה]בפייתון יש ארבע צורות להגדרת מחרוזת:
'<content>'
"<content>"
"""<content>"""
'''<content>'''
כאשר content הוא רצף התווים של המחרוזת. במילים אחרות, בפייתון, מחרוזת היא רצף תווים המופיע בין התווים ' ', בין התווים " ", או בין התווים """ """.
להלן מספר דוגמאות בעבודה אינטראקטיבית:
>>> 'This is a single quotes string'
'This is a single quotes string'
>>> "This is a double quotes string"
'This is a double quotes string'
>>> """This, too, is a string"""
'This, too, is a string'
כאשר מרכאות משולשות מאפשרות לפרוס טקסט על גבי מספר שורות:
>>> str="""Hello
... World"""
>>> str
'Hello\nWorld'
רצף תווים סתם (ללא המרכאות) - אינו מחרוזת:
>>> This is not a string
File "<stdin>", line 1
This is not a string
^
SyntaxError: invalid syntax
מציאת אורך מחרוזת
[עריכה]למציאת אורך של מחרוזת יש לרשום:
len(s)
כאשר s היא מחרוזת.
לדוגמה:
>>> len('Hello, world!')
13
שרשור מחרוזות
[עריכה]כדי לשרשר שתי מחרוזות, יש לרשום:
<str_0> + <str_1>
כאשר str_0 וstr_1 הן מחרוזות.
לדוגמה:
>>> 'Hello, ' + 'world!'
'Hello, world!'
שימו לב: במקרה שרוצים לשלב משתנים במחרוזות אין להשתמש בשיטה זו, אלא להשתמש בפונקציה format (הסבר מפורט יבוא בהמשך הפרק). |
השימוש בפונקציה join
[עריכה]הפונקציה join מכניסה מחרוזת נתונה בין כל תו של מחרוזת אחרת:
>>> ','.join('comma-seperated-text')
'c,o,m,m,a,-,s,e,p,e,r,a,t,e,d,-,t,e,x,t'
>>> ' '.join('comma-seperated-text')
'c o m m a - s e p e r a t e d - t e x t'
>>> '**'.join('comma-seperated-text')
'c**o**m**m**a**-**s**e**p**e**r**a**t**e**d**-**t**e**x**t'
לחילופין, אם הפונקציה join מקבלת מערך של מחרוזות, מתקבל שרשור עם תו מפריד:
>>> ','.join(['comma','seperated','text'])
'comma,seperated,text'
פיצול מחרוזות
[עריכה]הפונקציה split מפצלת בברירת המחדל לפי רווחים, או לפי delimiter (תו מפריד) אחר המועבר אליה:
>>> 'Hello World'.split()
['Hello', 'World']
>>> 'Hello-World'.split('-')
['Hello', 'World']
>>> 'Hello World'.split('o')
['Hell', ' W', 'rld']
הדפסת מחרוזת
[עריכה]קל מאוד להדפיס מחרוזות, ואף ראינו זאת בשלום עולם!. רושמים:
print <str>
כאשר str היא מחרוזת.
לדוגמה (כפי שכבר ראינו):
>>> print 'Hello, world!'
Hello, world!
תקציר הממשק
[עריכה]פונקציות פנימיות
[עריכה]str.upper()
- הופך את כל האותיות לאותיות גדולות (Uppercase).str.lower()
- הופך את כל האותיות לאותיות קטנות (Lowercase).str.join
- שרשור מחרוזות.str.split('delimiter')
- פיצול מחרוזות.str.startswith('something')
- פונקציה בוליאנית המחזירה 'True' אם המחרוזת str מתחילה ב-'something'.str.endswith('something')
- פונקציה בוליאנית המחזירה 'True' אם המחרוזת str מסתיימת ב-'something'.
פונקציות חיצוניות
[עריכה]len(str)
- אורך המחרוזת.cmp(str1,str2)
- השוואה בין מחרוזות. מחזיר 0 אם המחרוזות זהות, 1 אם ערך קידוד התוים במחרוזת הראשונה גדול מזו של השניה, או -1 אם ערך קידוד התוים במחרוזת השניה גדול מאשר בראשונה.- פונקציית CMP לא קיימת בגרסת 3.
צירוף מחרוזת ומשתנים
[עריכה]על מנת לצרף בצורה יעילה משתנים בתוך מחרוזת, יש להוסיף במקום המשתנה את המספר הקודם למספר המשתנה (לדוגמה: עבור המשתנה הראשון נכתוב 0 - מאחר שהספירה בתכנות מתחילה מ־0 ולא מ־1) בתוך סוגריים מסולסלים ולאחר מכן להוסיף למחרוזת את הפונקציה format ולספק כערכים את המשתנים שאנו רוצים להכניס, למשל:
w = "world"
print "Hello {0}!".format(w)
תדפיס "Hello world". נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מספרים ופעולות חשבוניות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
דף זה מסביר את סוגי המספרים בפייתון ופעולות החשבון הבסיסיות שהן חלק מהשפה. פייתון תומכת במספרים שלמים, מספרי נקודה צפה, ואפילו מספרים מרוכבים, וכוללת את פעולות חשבון הבסיסיות (כמו חיבור או כפל) עליהם.
פעולות חשבוניות מתקדמות יותר, לדוגמה פעולות טריגונומטריות, אינן חלק מהשפה אלא שייכות לספריה הסטנדרטית.
הפעולות הבסיסיות
[עריכה]פייתון מאפשרת לבצע שש פעולות חשבונות.
פעולה | סימן | דוגמא |
---|---|---|
חזקה ושורש | **
|
25 = 2 ** 5
|
כפל | *
|
6 = 2 * 3
|
חילוק | /
|
4.66666666 = 3 / 14
|
חילוק בתצוגת מנה שלמה int
(Floored division ) |
//
|
4 = 3 // 14
|
שארית (modulo) | %
|
2 = 3 % 14
|
חיבור | +
|
3 = 1 + 2
|
חיסור | -
|
1 = 3 - 4
|
- נהוג להניח רווח משני צדדי האופרטור בעת השימוש בו.
להלן מספר דוגמאות בעבודה אינטראקטיבית:
>>> 4 + 2
6
>>> 4 * 2
8
>>> 4 / 2
2
>>> 4 % 2
0
>>> 4 ** 2
16
נשים לב שלאחר כל פעולה חשבונית (שאת סופה אנו מציינים בהקשת Enter, כמובן), המתרגם האינטראקטיבי מדפיס את התוצאה.
שורשים
[עריכה]על פי כללי חזקות ועל כן ניתן לבצע חישוב של שורשים באמצעות העלאת חזקה. למשל,
>>> 25 ** (0.5)
5
>>> 9 ** (0.333)
2.0785
סדר פעולות החשבון
[עריכה]סדר פעולות החשבון בפייתון הוא המקובל באלגברה בסיסית, ולכן כפל (*),לדוגמה, מבוצע לפני חיבור (+).
>>> 2 + 3 * 5
17
בדיוק כבאלגברה בסיסית, ניתן להשתמש בסוגריים כדי לציין סדר פעולות שונה.
>>> (2 + 3) * 5
25
טיפוסים
[עריכה]עתה במקום לכתוב ביטוים נדפיס מחרוזות:
print "2 + 2 =", 2 + 2
print "3 * 4 is", 3 * 4
print "100 - 1 is", 100 - 1
print "(33 + 2) / 5 + 11.5 is", (33 + 2) / 5 + 11.5
והנה הפלט (output) של התוכנית
2 + 2 = 4 3 * 4 is 12 100 - 1 is 99 (33 + 2) / 5 + 11.5 is 18.5
כפי שניתן לראות פייתון יכול להפוך את המחשב החזק שלך למחשבון פשוט.
בדוגמא זו רואים שאחרי פקודת ההדפסה ישנם שני משתנים שמופרדים בפסיק. בשורה הראשונה
print "2 + 2 =", 2 + 2
המשתנה הראשון הוא המחרוזת " = 2 + 2"
והמשתנה השני הוא הביטוי המתמטי 2 + 2
, אשר בדרך כלל נקרא הביטוי (expression).
מה שחשוב לציין הוא שמחרוזת מודפסת כמו שהיא (ללא המרכאות מצדדיה) ואילו הביטוי המתמטי הינו הערך האמיתי שלו כלומר ממיר את ערכו בפועל.
סוגי מספרים
[עריכה]מבחינה אלגברית, אין הבדל בין חיבור שני מספר שלמים לבין חיבור שני מספרים עשרוניים. במחשב, לעומת זאת, יש טיפוסים שונים להחזקת מספרים.
מספרים שלמים
[עריכה]כאשר אנו מבצעים פעולות חשבון בין מספרים שלמים (int) התוצאה המתקבלת תמיד תהיה בתצוגת int פרט לחילוק. גם כאשר התוצאה היא מספר שלם.
>>> 17 / 5
3.4
>>> 4/ 4
1.0
כאשר נרצה שהתוצאה המתקבלת תהיה בתוצגת int דהינו ללא שארית נוסיף מקף נוסף
>>> 4 // 4
1
>>> 17 // 5
3
מספרים עשרוניים
[עריכה]פייתון תומכת גם במספרים עשרוניים (מספרי נקודה צפה ובאנגלית float). כל פעולה על מספרים כאלה תניב תוצאה מאותו סוג:
>>> 2.5 * 6
15.0
>>> (2.0 + 3.0) / 2
2.5
>>> 2/4
0
>>> 2/float(4)
0.5
פעולות מעורבות
[עריכה]כאשר המתרגם מזהה פעולות חשבוניות על סוגים שונים של מספרים (לדוגמה, חיבור מספר שלם ומספר נקודה צפה), הוא אוטומטית ממיר את כל המספרים לסוג הרחב מבין השניים.
כך, לדוגמה:
>>> 2 + 3.0
5.0
>>> (2 + 3) / 2.0
2.5
מספרים מרוכבים
[עריכה]פייתון תומכת אפילו במספרים מרוכבים. מספר מרוכב נרשם בצורה
<real_part> + <imaginary_part>j
כאשר real_part הוא החלק הממשי, וimaginary_part הוא החלק הדמיוני.
הקטע הבא, לדוגמא, מראה הכפלת שני מספרים מרוכבים:
>>> (1 + 2j) * (3 + 5j)
(-7+11j)
>>>
ניתן לחלץ את החלק הממשי והמדומה:
>>> x=1+2j
>>> x.real
1.0
>>> x.imag
2.0
- שימו לב: החלק הממשי והמדומה שניהם מטיפוס float.
על מנת לבצע פעולות חשבוניות מורכבות, יש לייבא את המודול cmath
:
שקלו לדלג על נושא זה יש להכיר את נושא המודולים. |
>>> import math as R
>>> import cmath as C
>>> x=1+2j
>>> R.sqrt(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float; use abs(z)
>>> C.sqrt(x)
(1.272019649514069+0.78615137775742328j)
>>> C.tan(x)
(0.033812826079896739+1.0147936161466338j)
דוגמה: המרה בין סוגי מעלות שונים
[עריכה]להלן דוגמה פשוטה מאד, שבה נשתמש גם בלולאות ופונקציות.
נניח ש-c מייצג טמפרטורה נתונה במעלות בשיטת Celsius, ואנו רוצים למצוא את f, המעלות בשיטת Fahrenheit. על פי נוסחה ידועה, f הוא 9 / 5 * c + 32. נניח גם שהדיוק אינו חשוב לנו במיוחד, ואנו מוכנים לעבוד במספרים שלמים (על אף שגיאת העיגול). להלן תכנית המקבלת כקלט מעלה בCelsius, ומדפיסה אותו בFahrenheit:
c = raw_input('Please enter degrees in Celsius: ')
f = 9 / 5 * float(c) + 32
print 'This is ' + str(f) + ' in Fahrenheit\n'
להפתעתנו (או לא), התוכנית פשוט תפלוט ערך שגוי. מדוע הדבר קורה? ראינו בפעולות חשבוניות על שלמים ונקודות צפות שכל פעולה על טיפוסים שלמים מניבה תמיד תוצאה מסוג שלם. 9 / 5, לכן, מתורגם ל1, ולכן מקבלים 1 * c + 32 בפועל.
נוכל לתקן זאת על ידי כך שנחליף את 9 / 5 ב1.8, שהוא מספר נקודה צפה:
f = 1.8 * float(c) + 32;
כעת מדובר בחישוב מעורב, והשלמים בצד ימין של הסימן = יומרו במספרי נקודה צפה. לאחר החישוב, הערך יושם ב-f שהוא מספר שלם, ורק החלק העשרוני יאבד (כלומר, נקבל רק שגיאת עיגול).
שימו לב כי הפונקציה raw_input מכניסה מחרוזת לתוך c ולא מספר, ואילו הפוקנציה float הופכת את המחרוזת למספר נקודה צפה (ניתן היה, במידת הצורך להשתמש ב-int במקום). לאחר מכן, הפקודה str הופכת את המספר חזרה למחרוזת על מנת שיהיה ניתן להציג את התוצאה כחלק ממחרוזת. הענין נידון לעומק בפרק הבא.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
המרות בין מספרים לעצמם ומחרוזות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
לפעמים יש לנו עצם מסוג אחד, אך אנו רוצים להשתמש בו בצורה שונה.
הבעיה
[עריכה]נתבונן לדוגמה בקטע הבא:
>>> 'I have ' + 'three' + ' apples'
'I have three apples'
עד כאן הכל בסדר: שירשרנו שלוש מחרוזות. גם הקטע הבא בסדר:
>>> 'I have ' + '3' + ' apples'
'I have 3 apples'
שוב שירשרנו שלוש מחרוזות, כשהאמצעית היא המחרוזת '3'. לעומת זאת, הקטע הבא יוצר בעיה:
>>> 'I have ' + 3 + ' apples'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
המתרגם מודיע שאינו יכול לשרשר מחרוזת ומספר שלם. כאן, ' I have' ו-' apples' הן מחרוזות, ואילו 3 הוא מספר שלם.
פונקציות ההמרה
[עריכה]כדי להמיר עצם מסוג אחד באותו עצם אך מסוג אחר (אם הדבר אפשרי), רושמים:
<new_type>(<obj>)
כאשר new_type הוא הסוג החדש, וobj הוא העצם. לדוגמה, כדי להמיר את המספר השלם 3 למחרוזת 3, רושמים:
>>> str(3)
'3'
כדי להמיר את המספר בנקודה-הצפה 3.1 למחרוזת '3.1', רושמים:
>>> str(3.1)
'3.1'
כדי להמיר את המחרוזת '3' למספר השלם 3, רושמים:
>>> int('3')
3
המרות לא-חוקיות
[עריכה]לא כל מחרוזת אפשר להמיר למספר שלם, שהרי יש מחרוזות שאינן מתארות מספר. במקרה שננסה לעשות כן, נקבל שגיאה:
>>> float('hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
עם זאת, ניתן להמיר מספר נקודה-צפה למספר שלם:
>>> int(3.1)
3
המרה זו היא חוקית, וכל שהיא עושה הוא לחתוך את החלק הלא-שלם מהמספר.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
במקום משתנים - עצמים ושמות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
על מנת שתכנית תוכל לשמור מידע (לדוגמה מקלט), לעבד מידע בחישובים מתמטיים, או לקבל החלטות על סמך מידע, יש לעתים צורך בנתינת שמות למידע.
עצמים
[עריכה]מהם עצמים? קשה לענות על כך. ראשית יש צורך בידע בתכנות מונחה עצמים, ופייתון מגדירה זאת בגמישות רבה אפילו יחסית לתחום. במקום לנסות להגדיר מה הם עצמים, ניתן דוגמה לעצמים שכבר פגשנו:
בהמשך הקרוב נראה עוד עצמים:
משתנה
[עריכה]פייתון מאפשרת לקשר שם לערך מורכב, לדוגמה כך:
>>> a = 2
כעת מקושר השם a למשתנה 2. בכל מקום בו אנו יכולים להשתמש בערך 2, נוכל גם להשתמש בשמו החדש, a. לדוגמה:
>>> a + 3
5
>>> 2 * a + 5
9
השמה של משתנה אחר בתוך משתנה
[עריכה]אפשר להשים יותר משם אחד לאותו משתנה. לדוגמה:
>>> a = 2
>>> b = a
>>>b
2
a הוא שם לעצם 2, ו-b הוא שם לעצם של a, כלומר גם כן 2.
הגדרה מחודשת של שם המשתנה
[עריכה]לאחר ששם נקשר לעצם, אפשר לקשור אותו לעצם אחר להבדיל ממספרים שנחשבים בלתי ניתנים לשינוי ("immutable data"). השם מפסיק להיות שמו של העצם הקודם, ועובר להיות שמו של העצם הבא. לדוגמה:
>>> a = 2
>>> a = 3
>>> a
3
תחילה a מוגדר כ-2, ולאחר מכן מוגדר כ- 3. כאשר אנו רושמים את שם המשתנה מתקבל ההגדרה ההאחרונה של המשתנה דהינו כלומר הגדרה מחודשת של משתנה מוחקת את הקודמת ומייצרת הגדרה חדשה. אפשר לחזור על כך מספר בלתי מוגבל של פעמים ולהחליף את ערכו של המשתנה בין טיפוסים שונים.
דוגמה: "קידום" שם
[עריכה]לאחר הרצת השורות הבאות, מה יהיה ערכו של b?
>>> a = 2
>>> b = a
>>> a = a + 1
נקליד ונבדוק:
>>> b
2
תחילה a הוא שמו של 2, וגם b הוא ערכו של 2. לאחר מכן נהיה a ערכו של 3. הדבר אינו משפיע כלל על השם b.
קישור בו-זמני
[עריכה]פייתון מאפשרת לקשר בו-זמנית מספר שמות לעצמים בהתאמה, לדוגמה כך:
>>> a, b, c = 2, 3, 4
יכולת זו מאפשרת לבצע דברים נחמדים, כמו החלפה בין שמות. לדוגמה:
>>> a = 2
>>> b = 3
>>> a, b = b, a
השורה הראשונה מקשרת בין השם a לעצם 2, השורה השניה מקשרת בין השם b לעצם 3, והשורה השלישית מקשרת בין a ו-b לבין העצמים של השמות b ו-a, ולכן למעשה מחליפה בין השמות. נוכל לבדוק זאת:
>>> a
3
>>> b
2
נדון בכך לעומק כאשר נדבר על n-יות וקישורים.
"משתנים"
[עריכה]לפעמים אומרים על שמות המקושרים לעצמים שהם משתנים. חשוב להבהיר מושג זה, שכן "משתנים" בפייתון אינם דומים למשתנים במספר שפות אחרות (לדוגמה שפת C): משתנה שפת C הוא כמעין תיבה שאפשר להכניס אליה ערך בכל פעם. ה"תיבה" קיימת בלי קשר לשאלה האם כלל הוכנס אליה ערך.
העצם None
[עריכה]None
הוא עצם מיוחד המציין "כלום". להלן דוגמה אפשרית לשימוש בו
grade = None
# Do some stuff
...
if grade != None:
print 'Your grade is', grade
else:
print 'Your grade is not in the system yet'
שימוש נוסף (וקשור) ב-None
הוא בכל מקום בו היינו משתמשים ב-NULL
בשפת C וב-NIL
בפסקל. הנה דוגמה לקוד המתפעל חוליה של רשימה מקושרת:
l = link()
l.value = 0
l.next = None
מרחב השמות (namespace)
[עריכה]פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
קישורים חיצוניים
[עריכה]
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
קלט ופלט
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
פלט וקלט הם מהרכיבים הבסיסיים בכל תוכנה, ומאפשרים ממשק בין המשתמש לבין התוכנה. הפלט מאפשר לתוכנית להוציא מידע אל המשתמש, והקלט מאפשר לתוכנה לקלוט מידע שמוכנס על ידי המשתמש.
פלט
[עריכה]כדי להדפיס למשתמש, משתמשים בפקודה print בצורה הזאת:
print <objs>
כאשר objs הם רצף של עצמים. המתרגם ימיר כל עצם למחרוזת, ידפיס את רצף המחרוזות מופרדים על ידי התו רווח, וידפיס תו מעבר-שורה (כלומר, יעבור לשורה חזרה).
הנה, לדוגמה, מה שראינו בפייתון/שלום עולם!:
>>> print 'Hello, world!'
Hello, world!
נוכל לרשום זאת גם כך:
>>> print 'Hello,', 'world!'
Hello, world!
נשים לב שאכן הודפסו כאן שתי מחרוזות מפורדות ברווח. התוצאה במקרה זה זהה למקרה הקודם.
להלן מספר צורות שונות להדפיס את המחרוזת 'I have 3 apples':
>>> print 'I have 3 apples'
I have 3 apples
>>> print 'I have', 3, 'apples'
I have 3 apples
>>> print 'I have ' + str(3) + ' apples'
I have 3 apples
הדפסת מספר איברים בפקודת פלט אחת
[עריכה]יש שתי אפשרויות בסיסיות להדפיס יותר מאיבר אחד.
אפשרות אחת היא להשתשמש בפקודת print
על מספר איברים מופרדים בפסיקים:
>>> print '1','*','2','=','2'
1 * 2 = 2
(נשים לב שהאיברים מודפסים מופרדים ע"י רווחים.)
אפשרות נוספת היא לשרשר מחרוזות ע"י האופרטור +
, ולהדפיס את התוצאה.
>>> print '1'+'*'+'2'+'='+'2'
1*2=2
דגלים, קובעי רוחב ודיוק
[עריכה]שימו לב: תוכן נושא זה אינו תקף לגרסה העתידית פייתון 3000. |
בדומה לשפת C, ניתן להשתמש בדגלים, קובעי רוחב ודיוק, כדי להנחות את פייתון כיצד לפרמט את הפלט.
ניקח לצורך הדוגמה את מטען האלקטרון:
e=1.602176487e-19
ניתן להגדיר את כמות הספרות אחרי הנקודה העשרונית שתציג פקודת print:
print '%.2e' % e # Output: 1.60e-19
print '%.5e' % e # Output: 1.60218e-19
print '%.30e' % e # Output: 1.602176487000000029461040573487e-19
- שימו לב כי ישנה שגיאת עיגול!
ניתן גם לשנות את גודל השדה. עבור הפקודה:
e=1.602176487e-19
print '%15.2e' % e; print '%15.4e' % e; print '%15.6e' % e;
יתקבל הפלט:
1.60e-19 1.6022e-19 1.602176e-19
כדאי לדעת: בעוד שפקודת print יורדת שורה אוטומטית, פקודת write לא עושה זאת. |
במקרה של מספר רב של נעלמים ניתן להשתמש בשתי שיטות:
>>> a=1.234
>>> b=5.678
>>> print 'a=%g, b=%g' % (a,b)
a=1.234, b=5.678
>>> print 'a=%(a)g, b=%(b)g' % vars()
a=1.234, b=5.678
קוד | משמעות |
---|---|
%d | מספר שלם |
%-d | מספר שלם עם יישור לשמאל |
%e | משתנה מטיפוס נקודה-צפה הנכתב בכתיב מדעי |
%s | מחרוזת. ניתן להשתמש בקוד זה כדי להציג מספרים, ופייתון ימיר אותם אוטומטית למחרוזת. |
פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
קלט
[עריכה]כדי לקלוט מידע מהמשתמש, אפשר להשתמש ב-raw_input (יש לציין שבפייתון 3 ומעלה הפקודה הוחלפה בinput), לפי הצורה הבאה:
name = raw_input()
כאשר name הוא שם אותו קושרים למה שהקליד המשתמש. לדוגמה:
>>> print 'Please enter your name:'
Please enter your name:
>>> name = raw_input()
Ami
(כאן הקליד המשתמש Ami). נבדוק למה מקושר name:
>>> name
'Ami'
הנה עוד דוגמה, הפעם לקלט מספר:
>>> print 'Please enter a number:'
Please enter a number:
>>> number = raw_input()
3
(כאן הקליד המשתמש 3). נבדוק למה מקושר number:
>>> number
3
כפי ששתי הדוגמאות הקודמות מראות, שכיח מאוד לבקש קלט מהמשתמש באמצעות בקשה טקסטואלית. פייתון, לכן, מאפשרת להציג את הפלט ע"י raw_input, כך:
>>> name = raw_input('Please enter your name: ')
Please enter your name: Ami
נשים לב שהקלט שהקליד המשתמש מופיע באותה שורה של ההודעה.
שימוש במודול sys
[עריכה]
שקלו לדלג על נושא זה קודם יש להכיר את נושא המודולים. |
יש לטעון את המודול sys על מנת להשתמש בפקודות הבאות:
import sys
קלט
[עריכה]האוביקט stdin הוא הקלט הסטנדרטי (standard input) וניתן לקרוא ממנו מידע בשני אופנים:
- שורה בודדת:
sys.stdin.readline()
- מספר שורות (בסופן יש להקיש Ctrl+D):
sys.stdin.read()
פלט
[עריכה]בדומה, ניתן להשתמש ב-sys.stdout.write
לצורך פלט:
sys.stdout.write('Hello!')
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
רשימות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
רשימה היא מבנה נתונים שמאפשר שמירה של משתנים רבים תחת אותו שם, כאשר כל אחד מהמשתנים מקבל מספר מזהה ייחודי. שימוש ברשימות מאפשר עבודה נוחה עם מידע שמורכב מחלקים רבים הקשורים זה לזה.
כדאי לדעת: רשימה בפייתון מקבילה (אך לא זהה) למערך ברוב השפות הנפוצות האחרות, לדוגמה מערך שפת C. |
הגדרת רשימה
[עריכה]רשימה בפייתון היא עצם מהצורה:
[<elements>]
כאשר elements היא איבר או יותר מופרדים על ידי פסיקים. לדוגמה,
[1, 2, 3]
היא רשימה של מספרים שלמים, ולעומת זאת
['Hello', 'world']
היא רשימה של מחרוזות. בניגוד לשפות רבות אחרות (וככל שפה דינמית), רשימה לא חייבת להיות הומוגנית: האיברים בה עשויים להיות מטיפוסים שונים. הנה רשימה שחלק מאיבריה מספרים, וחלקם מחרוזות:
['Hello', 1, 2.2, 'world']
פונקציות פנימיות
[עריכה]a_list.reverse()
- הופך את סדר הרשימה.a_list.sort()
- ממיין את הרשימה.
פונקציות חיצוניות
[עריכה]str.split(<delimiter>)
- מפצל מחרוזת לרשימה בהתאם ל-delimiter. ברירת המחדל היא רווח.sorted_list=sorted(original_list)
- מחזיר רשימה ממוינת ללא שינוי הרשימה המקורית.
רשימות, עצמים, ושמות
[עריכה]היות שרשימה היא עצם, אז אפשר לקשור לה שם. כך, לדוגמה:
>>> my_list = ['Hello', 1, 2.2, 'world']
כמו כן, כפי שכבר ראינו, בכל מקום שמשתמשים בעצמים, אפשר גם להשתמש בשמות לעצמים. לכן אפשר להגדיר איברי רשימה בעזרת עצמים, שמות, או שילובים שלהם. כך, לדוגמה:
>>> a = 2
>>> b = 3
>>> [a, b, 'hello', 5]
[2, 3, 'hello', 5]
מציאת אורך
[עריכה]כדי למצוא אורך רשימה, רושמים
len(<lst>)
כאשר lst היא רשימה. התוצאה היא עצם מסוג מספר שלם. כך, לדוגמה:
>>> len([2, 3])
2
>>> a = [1, 2, 3]
>>> len(a)
3
>>> len(a) + 2 * 3
9
גישה לאיבר
[עריכה]כדי לגשת לאיבר, רושמים:
<lst>[<pos>]
כאשר lst היא רשימה, ו-pos הוא המיקום בתוך הרשימה.
שימו לב: האיבר הראשון ברשימה הוא 0, ולא 1. |
תחביר | משמעות |
---|---|
a[0] | האיבר הראשון. |
a[-1] | האיבר האחרון. |
a[-2] | האיבר לפני האחרון. |
a[0:2] or a[:2] | שני האיברים הראשונים. |
a[-2:] | שני האיברים האחרונים. |
a[:-1] | כל האיברים פרט לאחרון. |
a[1:] | כל האיברים פרט לראשון. |
לדוגמה:
>>> a = [2, 3, 4]
>>> a[0]
2
>>> a[1]
3
המתרגם מזהה מצב בו גולשים מגבולות הרשימה:
>>> a = [2, 3]
>>> a[5]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
שינוי איבר
[עריכה]אפשר לשנות איבר רשימה, כפי שמראה הדוגמה הבאה:
>>> a = [2, 3, 4]
>>> a
[2, 3, 4]
>>> a[0] = 10
>>> a
[10, 3, 4]
גם כאן, אי אפשר לשנות איבר שמיקומו גולש מהרשימה:
>>> a = [2, 3]
>>> a[5] = 8
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
הוספת איבר
[עריכה]כדי להוסיף איבר לסוף הרשימה, רושמים:
<lst>.append(<obj>)
או:
<lst>[-1:]=[<lst>[-1],<obj>]
וכדי להוסיף איבר לתחילת הרשימה:
<lst>[:0]=[<obj>]
כאשר lst היא רשימה, ו-obj הוא העצם להוסיף לסופה. כך, לדוגמה:
>>> a = [2, 4, 6]
>>> a.append(8)
>>> a
[2, 4, 6, 8]
>>> a[:0]=[-2,0]
>>> a
[-2, 0, 2, 4, 6, 8]
>>> a[3:]=[1]
>>> a
[-2, 0, 2, 1]
>>> a[-1:]=[4,6,8]
>>> a
[-2, 0, 2, 4, 6, 8]
מציאת אינדקס של איבר
[עריכה]>>> phrase=['three','different','words']
>>> phrase.index('words')
2
>>> phrase.index('three')
0
בדיקת שייכות
[עריכה]ניתן לבדוק שייכות לרשימה באמצעות האופרטור in
:
>>> shopping=['milk','bread']
>>> 'juice' in shopping
False
>>> for product in shopping: # זאת לולאה, הנלמדת בפרק מתקדם יותר.
... print product
...
milk
bread
מחיקת איבר
[עריכה]מוחקים איבר ברשימה בצורה:
del <lst>[<index>]
כאשר lst היא רשימה, ו-index הוא אינדקס האיבר למחיקה. לדוגמה:
>>> a = [2, 3, 4]
>>> a
[2, 3, 4]
>>> del a[1]
>>> a
[2, 4]
גם כאן, אי אפשר למחוק איבר שמיקומו גולש מהרשימה:
>>> del a[10]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
שרשור רשימות
[עריכה]משרשרים רשימות בצורה:
<lst>.extend(<other_lst>)
כאשר lst היא רשימה, וother_lst היא רשימה אחרת. הפעולה תשרשר את איברי other_lst לסוף lst, ולא תשנה את other_lst. לדוגמה:
>>> a = [2, 3, 4]
>>> b = [1, 5]
>>> a.extend(b)
>>> a
[2, 3, 4, 1, 5]
>>> b
[1, 5]
הרשימה range
[עריכה]פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
בניית רשימות ע"י אפיון
[עריכה]
שקלו לדלג על נושא זה נושא זה מניח שאתה מכיר את הנושאים לולאות וביטויים בוליאניים ותנאים. אם זה אינו המצב, שקול לחזור לכאן לאחר שלמדת נושאים אלה. |
לעתים מאפיינים במתמטיקה קבוצה כ. הכוונה היא שהקבוצה מכילה, לכל x שעבורו מתקיים , את . לדוגמה:
- הקבוצה היא קבוצת כל האיברים כך ש-x שייכת לקבוצה . בצורה אחרת, זוהי פשוט הקבוצה .
- הקבוצה היא קבוצת כל האיברים x2 כך ש-x שייכת לקבוצה . בצורה אחרת, זוהי פשוט הקבוצה .
- הקבוצה היא קבוצת כל האיברים x כך ש-x שייכת לקבוצה , ו-x זוגי. במילים אחרות, זוהי פשוט הקבוצה .
עכשיו תורכם: מהם איברי הקבוצה ? |
פייתון מאפשרת לבנות רשימות ע"י אפיון כזה, בצורה:
[<expression> for <var> in <lst>]
או:
[<expression> for <var> in <lst> if <condition>]
כאשר var הוא ביטוי, lst היא רשימה, condition הוא ביטוי בוליאני (שיכול להיות תלוי ב-var), ו-expression הוא ביטוי (שיכול להיות תלוי ב-var).
לדוגמה:
[x for x in range(10)]
שקולה לחלוטין ל:
range(10)
אם נרצה רק את האיברים הזוגיים, נוכל לכתוב כך:
[x for x in range(10) if x % 2 == 0]
הנה מצב בו expression מעט מורכב יותר:
[x**2 for x in range(10)]
expression גם יכול להיות מורכב מפונקציה:
def divides_by_three(n):
return n % 3 == 0
[x**2 for x in range(10) if divides_by_three(x)]
או בצורה כללית (נניח שהפונקציה f והרשימה a_list הוגדרו כבר):
y=[f(x) for x in a_list]
ניתן לבצע "מיפוי" שכזה גם בעזרת פונקצית map
:
map(f,a_list)
לדוגמה:
>>> import math
>>> map(math.sqrt,[4,9,16])
[2.0, 3.0, 4.0]
דוגמאות נוספות:
>>> a_list=[(x,x**2) for x in range(5)]
>>> a_list
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)]
>>> for (x,y) in a_list:
... print x,y
...
0 0
1 1
2 4
3 9
4 16
>>> [[x,y] for x in range(3) for y in range(7,10)]
[[0, 7], [0, 8], [0, 9], [1, 7], [1, 8], [1, 9], [2, 7], [2, 8], [2, 9]]
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
ביטויים בוליאניים ותנאים
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
כדי להשתמש בנתונים שנקלטו מהמשתמש ולנתב בעזרתם את התוכנה, מדי פעם צריכים לעשות בדיקה של הנתונים.
ערכים בוליאניים
[עריכה]אמת ושקר, וייצוגם בפייתון
[עריכה]ביטוי בוליאני הוא ביטוי שיכול לקבל את הערכים "אמת" ו"שקר". לעתים צריך בתכניות מחשב להכריע האם דבר הוא אמת או שקר, לדוגמה, האם נכון שערכו של המשתנה x הוא 6, או האם שקר הוא שערכו של המשתנה x קטן מערכו של המשתנה y.
בפייתון נהוגה המוסכמה לפיה "שקר" מצויין על ידי:
- הערך False
- הערך המספרי 0
- אוסף ריק - רשימה ריקה, מחרוזת ריקה וכו'
- עצם מיוחד, None, שנועד לסמן "כלום"
- ערך שקר המוחזר מהמתודה __bool__ אם ישנה כזאת.
ערכים אחרים מציין "אמת". בהמשך דף זה ובלולאות נראה כיצד לגרום למחשב לבצע פעולות שונות בהתאם לשאלה האם ערך כלשהו הוא אמת או שקר.
אופרטורים בוליאניים
[עריכה]פייתון כוללת מספר אופרטורים בוליאניים, כלומר אופרטורים שתוצאתם היא "אמת" או "שקר". לדוגמה, כדי לבדוק האם ערך המשתנה x הוא 6, רושמים
x == 6
כאשר יתבצע קטע קוד זה, יתרגם אותו המחשב ל"אמת" (ערך כלשהו שאינו 0) אם ערך x אכן 6, או ל"שקר" (הערך המספרי 0) אם ערכו שונה.
שים לב להבדל בין האופרטור == לבין פעולת הקישור =.
לפייתון האופרטורים הבוליאניים הבאים:
- == (להבדיל מ= המשמש להשמה) - האם שני צדי הביטוי שווים
- =! - האם שני צדי הביטוי שונים
- > - האם הצד הימני של הביטוי גדול מצדו השמאלי
- < - האם הצד הימני של הביטוי קטן מצדו השמאלי
- => - האם הצד הימני של הביטוי גדול או שווה לצדו השמאלי
- =< - האם הצד הימני של הביטוי קטן או שווה לצדו השמאלי
תוכל לראות כיצד משתמשים באופרטורים בוליאניים בתנאי if (ייתכן שתרצה לבדוק זאת בקצרה לפני המעבר לנושא הבא).
אופרטור הזהות is
[עריכה]פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
אופרטורים לוגיים
[עריכה]גימום, איווי, ושלילה
[עריכה]ביטוי בוליאני יכול להיות מורכב גם מאוסף של ביטויים בוליאניים פשוטים יותר, המחוברים על ידי קשרים לוגיים, למשל: "אם x שווה 5 או x שווה 6", או: "אם x גדול מ-y וגם y גדול מ-z", וכדומה.
גימום (conjunction בלעז), כלומר הקשר הלוגי "וגם", מיוצג על ידי and:
<condition_1> and <condition_2>
כאשר condition_1 וcondition_2 הם שני תנאים בוליאניים, והגימום הוא אמת אם ורק אם שניהם אמת. לדוגמה:
x == 5 and y == 6
הוא התנאי שערכו של x הוא 5 וכן ערכו של y הוא 6.
איווי (disjunction בלעז), כלומר הקשר הלוגי "או", מיוצג על ידי or:
<condition_1> or <condition_2>
כאשר condition_1 וcondition_2 הם שני תנאים בוליאניים, והאיווי הוא אמת אם ורק אם לפחות אחד מהם אמת אמת. לדוגמה:
x == 5 or y == 6
הוא התנאי שערכו של x הוא 5 או שערכו של y הוא 6.
שלילה (negation בלעז), כלומר הקשר הלוגי "לא", מיוצג על ידי not:
not <condition>
כאשר condition הוא תנאי בוליאני, והשלילה היא אמת אם ורק אם התנאי הוא שקר. לדוגמה:
not (x == 5)
הוא התנאי השולל שערכו של x הוא 5.
ניתן גם ליצור תנאים המורכבים ממספר גדול יותר של ביטויים וקשרים לוגיים, ולהשתמש בסוגריים ע"מ לקבוע את סדר חישובם. למשל:
a > b or (a <= b and b==5)
תוכל לראות כיצד משתמשים באופרטורים בוליאניים בתנאי if (ייתכן שתרצה לבדוק זאת בקצרה לפני המעבר לנושא הבא).
הערכת ביטויים לוגיים מורכבים
[עריכה]
שקלו לדלג על נושא זה הקוד הנוצר משימוש בטכניקה זו עלול לבלבל מתכנתים מתחילים. עם זאת, טכניקה זו נמצאת בשימוש רב, בעיקר במערכים, ולכן מומלץ שתשוב לנושא כאן כשתגיע לשם. |
בעת הרצת התוכנית מתבצע חישוב של תנאי מורכב משמאל לימין, ובשימוש בקצר לוגי (שיוסבר להלן).
נתבונן בתנאי המורכב:
x == 5 or y == 6
מבין שני הביטויים כאן, הביטוי השמאלי, x == 5 הוא זה שיוערך ראשון. כעת יש שתי אפשרויות:
- אם ביטוי זה הוא שקר, עדיין יכול הביטוי המורכב, x == 5 or y == 6, להיות אמת - יש לבדוק אם הביטוי הימני, y == 6, הוא אמת.
- אם ביטוי זה הוא אמת, אז הביטוי המורכב, x == 5 or y == 6, בהכרח אמת. אין צורך אפילו לבדוק את הביטוי הימני. השפה מבטיחה במקרה זה לערוך קצר לוגי - היא כלל לא תעריך את y == 6.
השפה מבטיחה שני סוגי קצרים לוגיים. בתנאי המורכב
<left_condition> or <right_condition>
לא יוערך הביטוי right_condition אם left_condition אמת. בתנאי המורכב
<left_condition> and <right_condition>
לא יוערך הביטוי right_condition אם left_condition שקר.
בפייתון משתמשים בקצרים לוגיים באופן תדיר. לדוגמה:
if x != 0 and 1 / x < 2:
print 'OK'
מבטיחה, על ידי קצר לוגי, שלא תתבצע בטעות חלוקה ב-0.
תנאי בקרה
[עריכה]תנאי בקרה (selection statements) מאפשרים לציין אילו קטעי קוד יבוצעו בהתאם לתנאים כלשהם.
if
[עריכה]משפטי תנאי מתחילים במילה if, לאחריו ביטוי בוליאני, ולאחריו הפקודה (או הבלוק) שיש לבצע במקרה שהביטוי הבוליאני אמת:
if <condition>:
<action>
כאשר condition הוא התנאי הבוליאני לבדיקה, ו-action הוא הפקודה (או הבלוק).
התרשים הבא מראה את התנאי בצורה גרפית:
לדוגמה, קטע הקוד:
if x == 6:
print 'x is 6'
ידפיס אם ערך x אכן 6 תתבצע ההדפסה (ואם לא - לא).
כמובן שנוכל ליצור תנאים מסובכים מעט יותר:
- אפשר להשתמש באופרטורים בוליאניים ולוגיים כדי ליצור תנאים בוליאניים מורכבים לבדיקת ה-if.
- אפשר להשתמש בבלוקים כדי לבצע רצף של פקודות במקרה שהתנאי אמת.
עכשיו תורכם: כתוב קטע שיבדוק האם ערך משתנה x הוא 5 או 6, ומדפיס הודעה אם אכן הדבר כן. |
if x == 5 or x == 6:
print 'x is either 5 or 6'
עכשיו תורכם: כתוב קטע שיבדוק האם ערך משתנה x הוא 5, ואם כן, ישים את הערך 1 למשתנה i, ו-2 למשתנה j. |
if x == 5:
i = 1
j = 2
else
[עריכה]לפעמים צריך לציין הן מה לעשות כשתנאי מתקיים, והן מה לעשות כשאינו מתקיים. במקרה זה אפשר להשתמש בתנאי if / else.
if <condition>:
<action>
else:
<alternative_action>
כאן condition הוא תנאי, action הוא פקודה (או בלוק) לביצוע אם התנאי מתקיים, ו-alternative_action הוא פקודה (או בלוק) לביצוע אם אינו מתקיים.
התרשים הבא מראה את התנאי בצורה גרפית:
לדוגמה:
if x==6:
y += 2
else:
y = 8
יחבר 2 ל-y אם x == 6, ויקבע את ערכו של y ל-8 אם ערכו של x אינו 6.
else if
[עריכה]לפעמים צריך לציין הן מה לעשות כשתנאי מתקיים, והן מה לעשות כשאינו מתקיים, אך תנאי אחר כן מתקיים. במקרה זה אפשר להשתמש בתנאי if / else if.
if <condition>:
<action>
else if <alternative_condition>:
<alternative_action>
כאן condition הוא תנאי, action הוא פקודה (או בלוק) לביצוע אם התנאי מתקיים, alternative_condition הוא תנאי לבדיקה אם condition הוא שקר, ו-alternative_action הוא פקודה (או בלוק) לביצוע אם condition הוא שקר אך alternative_condition הוא אמת.
לדוגמה:
if x==6 :
y += 2
else if x % 2 == 0:
y = 8
יחבר 2 ל-y אם x == 6, ויקבע את ערכו של y ל-8 אם ערכו של x אינו 6 אך x זוגי.
כדאי לדעת: במקום לכתובelse if ניתן לכתוב פשוט elif .
|
שילובי if / else if / else
[עריכה]ניתן לשלב בין שלושת תנאי הבקרה שראינו. המבנה הכללי ביותר הוא:
- תנאי if, שלאחריו
- אפס או יותר תנאי if else, שלאחר האחרון שבהם (אם יש כאלה)
- תנאי else
בדיקת תוכן של משתנה
[עריכה]על מנת לבדוק ערך של משתנה, אפשר להשתמש באופרטור is
:
if object_name is value:
...
if object_name is not value:
...
אפשר גם להשתמש באופרטור שוויון:
if object_name == value:
...
if object_name != value:
...
בלוקים
[עריכה]פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
אופרטור התניה
[עריכה]אופרטור התניה מאפשר לציין ערך שתלוי בתנאי כלשהו. אופן כתיבתו בצורה:
<true_value> if <condition> else <false_value>
כאשר condition הוא ביטוי בוליאני, true_value הוא הערך אם condition תקף, ו-false_value הוא הערך אחרת. לדוגמה הביטוי
1 if a == 3 else 2
הוא בעל הערך 1 אם a אכן שווה ל-3, והוא בעל הערך 2 אחרת.
חשוב להבין שאפשר להשתמש באופרטור התניה כערך לכל דבר. לדוגמה, ניתן לכתוב:
b = 1 if a == 3 else 2
וכן
print 'moshe' if a > 5 else 'yaakov'
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
לולאות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
לולאות משמשות לחזרה על קטע קוד מספר פעמים. לולאה חוסכת בזמן כתיבת התוכנה ומסדרת את הקוד.
הצורך בלולאות
[עריכה]במספרים ופעולות חשבוניות, ראינו דוגמה להמרה בין סוגי מעלות שונים כיצד להמיר ממעלות בCelsius למעלות בFahrenheit. נניח שאנו רוצים להדפיס את התרגום למעלות Fahrenheit של מעלות הCelsius בערכים 0, 2, 4, ..., 20. ננסה לעשות זאת כך:
c = 0;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 2;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 4;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 6;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 8;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 10;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 12;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 14;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 16;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 18;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = 20;
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
קל לראות שמשהו בעייתי בקוד, והבעייתיות היתה גוברת לו היינו פועלים בתחום גדול יותר, לדוגמה 0, 2, 4, ..., 100. בין היתר:
- הקוד ארוך ומסורבל מאד.
- תמיד ייתכן שהקוד כולל שגיאה כלשהי: ייתכן שטעינו בהעתקת הנוסחה הממירה, לדוגמה. כאן נצטרך לתקן את הקוד ב-11 מקומות.
בפרק זה נלמד להשתמש בלולאות, המאפשרות לתרגם את הקוד הקודם לקוד תמציתי יותר:
for c in range(0, 20, 2):
f = 1.8 * c + 32;
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
שתוצאתו דומה.
לולאת while
[עריכה]לולאת while היא לולאה הפועלת כל עוד תנאי מוגדר מתקיים. אופן כתיבת הלולאה הוא:
while <condition>:
<action>
כאשר condition הוא תנאי בוליאני, ו-action הוא ביטוי (או בלוק) המתבצע כל עוד התנאי הבוליאני מתקיים.
לדוגמה, קטע הקוד הבא מדפיס את המספרים 1-20 (כל אחד בשורה):
i = 1
while i <= 20:
print i
i = i + 1
עכשיו תורכם: כתבו תוכנית שמדפיסה את כל המספרים האי-זוגיים מ-1 עד 20, השתמשו בלולאת while. |
i = 1
while i <= 20:
print i
i = i + 2
לולאת for
[עריכה]לולאת for הנה לרוב תמציתית יותר מלולאת while. לולאת while דורשת פקודה שתעצור אותה שתופסת מקום רב בזכרון, לכן עדיף להשתמש בלולאת for.
מעבר על רשימה
[עריכה]לולאת for עוברת על כל אחד מאיברי רשימה. אופן כתיבת הלולאה הוא:
for <name> in <lst>:
<action>
כאשר name הוא שם, lst היא רשימה, ו-action היא פעולה לביצוע על כל איבר. הלולאה תעבור איבר איבר, תשייך את השם name לאיבר, ותבצע את action.
לדוגמה, הלולאה הבא תדפיס שבע מחרוזות, כל יום בשורה נפרדת:
for day in ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']:
print day
עכשיו תורכם: מה תדפיס הלולאה? |
for day in ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']:
print 'Today is ' + day
Today is Sunday Today is Monday Today is Tuesday Today is Wednesday Today is Thursday Today is Friday Today is Saturday
עכשיו תורכם: כתבו תוכנית שמדפיסה את כל המספרים האי-זוגיים מ-1 עד 20, השתמשו בלולאת for. |
for i in [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]:
print i
השימוש ב-range
[עריכה]לולאת for הנה נוחה במיוחד כאשר משתמשים בה בצירוף הרשימה range.
לדוגמה, קטע הקוד הבא מדפיס את המספרים 0-19 (כל אחד בשורה):
for i in range(20):
print i
עכשיו תורכם: כתבו תוכנית שמדפיסה את כל המספרים האי-זוגיים מ-1 עד 20, השתמשו בלולאת for. |
for i in range(1, 20, 2):
print i
ואפשר גם כך:
for i in range(10):
print 2 * i + 1
הערה לבעלי נסיון בשפות אחרות
[עריכה]ברוב שפות התכנות, לולאת for מקדמת אינדקסים מספריים. לכן, קוד פייתון של בעלי נסיון בשפות אחרות נראה לפעמים כך:
a = ['Shalom', 'olam', 'ma', 'shlomha']
for i in range(len(a)):
print a[i]
חשוב להבין שזה לא פיתוני, ואפשר לכתוב זאת בצורה פשוטה יותר, כך:
a = ['Shalom', 'olam', 'ma', 'shlomha']
for i in a:
print i
סכנות בתנאי העצירה
[עריכה]כשכותבים לולאות, יש לוודא שתנאי העצירה אכן יתקיים בהכרח בוודאות - המהדר לא יעשה זאת בשבילנו. נתבונן, לדוגמה, בקטע הקוד הבא:
i = 2
while i < 20 or i > 20:
print i
לולאה זו לא תעצר לעולם, שכן התנאי להמשך הלולאה תמיד יתקיים. כאשר קטע קוד זה יופעל, התוכנית תראה כאילו ש"קפאה".
דוגמה לשילוב פלט/קלט, תנאים, ולולאות
[עריכה]נסיים בתוכנית קטנה המדגימה את השימוש בתנאים ולולאות. התוכנית קולטת מהמשתמש שני מספרים, ומדפיסה הודעה האומרת מה היחס ביניהם. אחר כך היא שואלת את המשתמש אם הוא רוצה להמשיך ולתת שני מספרים נוספים, וכך הלאה, עד שהמשתמש בוחר להפסיק.
asked_to_quit = False
while not asked_to_quit:
print 'Please enter two numbers with a space between them:'
a = raw_input()
b = raw_input()
if a > b:
print str(a) + ' is bigger than ' + str(b)
elif a < b:
print str(a) + ' is smaller than ' + str(b)
else:
print 'the numbers are equal'
print 'Please enter 1 to repeat, any other number to quit.'
response=int(raw_input())
asked_to_quit = response != 1
להלן הסבר לתוכנית.
נתבונן ראשית במבנה של הקוד בתוך main. הקוד הוא למעשה כמעט כולו לולאת while:
asked_to_quit = False
while not asked_to_quit:
...
כלומר, עושים פעולה כלשהי כל עוד ערך asked_to_quit הוא False. מתי נקבע ערכו של asked_to_quit? בתוך הלולאה, נוכל לראות את רצף השורות הבאות:
print 'Please enter 1 to repeat, any other number to quit.'
response = raw_input()
asked_to_quit = respons == 1
השורות מבקשות מהמשתמש להכניס ערך (הקובע האם להמשיך בתוכנית), וקולטות את הערך למשתנה response. אם ערך זה הוא 1, אז קובעים את ערכו של asked_to_quit ל-True.
חוץ מכך, הלולאה מתחילה בשורות:
print 'Please enter two numbers with a space between them:'
a = raw_input()
b = raw_input()
המבקשות מהמשתמש להכניס שני ערכים. לאחר שהוכנסו שני הערכים, השורות הבאות מדפיסות את היחס ביניהם:
if a > b:
print str(a) + ' is bigger than ' + str(b)
else if ( a < b )
print str(a) + ' is bigger than ' + str(b)
else
print 'the numbers are equal'
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
טאפל
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2 טאפלים (n-יות סדורות) בפייתון דומות לרשימות בלתי ניתנות לשינוי.
הגדרת טאפל
[עריכה]טאפל (tuple) בפייתון הוא עצם מהצורה:
(<elements>)
כאשר elements היא איבר או יותר מופרדים על ידי פסיקים. לדוגמה,
(1, 2, 3)
הוא טאפל של מספרים שלמים, ולעומת זאת
('Hello', 'world')
הוא טאפל של מחרוזות. טאפל לא חייב להיות הומוגני. הנה טאפל שחלק מאיבריו מספרים, וחלקם מחרוזות:
('Hello', 1, 2.2, 'world')
כדאי לדעת: * הטאפלים הנפוצים ביותר בשימוש הן בעלות שני איברים או שלושה איברים. נקרא לטאפלים אלו זוגות ושלישיות, בהתאמה.
|
דמיון ושוני לרשימות
[עריכה]טאפל דומה לרשימה בכך שניגשים לאיברי כל אחד מהם באותה צורה. לדוגמה:
>>> a = [1, 2, 3]
>>> b = (1, 2, 3)
>>> a[0]
1
>>> b[0]
1
כמו כן, בדומה לרשימות, ניתן לבדוק שייכות לטאפל באמצעות האופרטור in
:
>>> shopping=('milk','bread')
>>> 'juice' in shopping
False
>>> for product in shopping:
... print product
...
milk
bread
השוני העיקרי הוא שרשימה היא עצם הניתן לשינוי, וטאפל איננו ניתן לשינוי. לדוגמה:
>>> a = [1, 2, 3]
>>> b = (1, 2, 3)
>>> a[0] = 13
>>> b[0] = 13
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
המרות בין טאפלים ורשימות
[עריכה]אפשר להמיר רשימה לטאפל על ידי כתיבת
tuple(<lst>)
כאשר lst היא רשימה. מצד שני, אפשר להמיר טאפל לרשימה על ידי כתיבת
list(<tp>)
כאשר tp הוא טאפל.
לדוגמה:
>>> a = [1, 2, 3]
>>> b = (1, 2, 3)
>>> a_as_tuple = tuple(a)
>>> b_as_list = list(b)
>>> a_as_tuple
(1, 2, 3)
>>> b_as_list
[1, 2, 3]
טאפלים וקישורים
[עריכה]בפייתון/פייתון גרסה 2/במקום משתנים - עצמים ושמות, ראינו שאפשר לקשור שמות לעצמים. פייתון גם מאפשר לקשור טאפלים של שמות לטאפלים של עצמים. במקרה זה, כל שם מקושר לעצם המקביל אליו.
נתבונן, לדוגמה, בקוד הבא:
>>> (a, b) = (2, 3)
הקוד פשוט קושר את a ל-2, ואת b ל-3. הוא למעשה מהווה קיצור של הקוד הבא:
>>> a = 2
>>> b = 3
כאשר מקשרים טאפלים של שמות לטאפלים של עצמים, אין אפילו צורך לכתוב את הסוגריים המציינים את הטאפלים. אפשר לכתוב את הקוד הקודם כך:
>>> a, b = 2, 3
כפי שראינו בקישור בו-זמני, אפשר להשתמש בזאת כדי להחליף קישורים:
>>> a = 'Hello'
>>> b = 'world!'
>>> a, b = b, a
טאפלים ולולאות
[עריכה]כבר ראינו בלולאת for שאפשר לקשר שם לכל אחד מעצמי רשימה. אם איברי הרשימה הם זוגות (או למעשה טאפל כלשהי), השם יקושר לכל זוג. לדוגמה:
>>> a = [(2, 3), (4, 5), (10, 11)]
>>> for i in a:
... print i
(2, 3)
(4, 5)
(10, 11)
מקשרת את השם a לכל זוג.
כאשר אנו יודעים בוודאות שכל איבר ברשימה הוא זוג (או למעשה טאפל כלשהו), נוכל להשתמש במה שראינו בטאפלים וקישורים, ולקשור זוג שמות לכל זוג עצמים. לדוגמה:
>>> a = [(2, 3), (4, 5), (10, 11)]
>>> for (x, y) in a:
... print x
2
4
10
מקשרת את הזוג (x, y) לכל זוג עצמים.
שימוש בפונקציות
[עריכה]
שקלו לדלג על נושא זה נושא זה מניח שאתה מכיר פונקציות. אם זה אינו המצב, מומלץ לחזור לכאן לאחר שתלמד נושא זה. |
לעתים נתקלים במצב שבו רוצים שפונקציה תחזיר יותר מערך אחד. טאפלים נוחים מאד לצורך כך.
לדוגמה, נניח שאנו רוצים לכתוב פונקציה min_and_max המקבלת שני מספרים, ומחזירה את הקטן ראשון, ואת הגדול שני. נוכל לכתוב זאת כך:
def min_and_max(a, b)
if a > b:
return (b, a)
else:
return (a, b)
(x, y) = min_and_max(2, 3)
היות שלא חייבים לסמן את הסוגריים כאן, אפשר לכתוב זאת גם כך:
x, y = min_and_max(2, 3)
כפי שראינו באופרטור התניה, ניתן לכתוב את הפוקנציה בקיצור יותר כך:
def min_and_max(a, b)
return (b, a) if a > b else (a, b)
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מילונים
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מילון הוא מבנה נתונים הממפה מפתחות (keys) לערכים (values) ביעילות ובנוחות.
מהו מילון?
[עריכה]לעתים רוצים למפות מפתחות לערכים. לדוגמה, אם יש לנו קבוצת תלמידים אשר נבחנו במבחן, ייתכן שנרצה למפות כל שם תלמיד לציון שקיבל במבחן. במילון זה, המפתחות הם שמות התלמידים, והערכים הם הציונים. מילון הוא מבנה נתונים פייתוני המאפשר לעשות דברים כאלה ביעילות ובנוחות. במילון פייתוני, הן המפתחות והן הערכים הם עצמים. קוראים הבקיאים בנושא המערך יכולים לדמות את המילון כמבנה כמו מערך, שבו ה"אינדקס" לא חייב להיות מספר, וטיפוס הנתונים של כל איבר במערך לא חייב להיות זהה.
כדאי לדעת: בספרות המקצועית, לעתים נקרא מילון (dictionary בלעז) בשם מערך אסוציאטיבי (associative array בלעז). הוא ממומש בפייתון באמצעות טבלת ערבול. |
הגדרת מילון
[עריכה]מבנה
[עריכה]מגדירים מילון בצורה:
d={}
כאשר items הם האיברים במילון. כל איבר הוא בצורה:
<key>:<value>
כאשר key הוא המפתח, וvalue הוא ערכו.
דוגמה
[עריכה]>>> {'foo':80, 'bar':90}
בונה מילון שבו 'foo' ממופה ל80, ו'bar' ממופה ל90. כמו כן:
>>> grades = {'foo':80, 'bar':90}
בונה מילון שבו 'foo' ממופה ל80, ו'bar' ממופה ל90, ומקשרת את השם grades למילון.
אפשר גם לבנות מילון ריק:
>>> grades = {}
בונה מילון ריק, ומשייכת את השם grades למילון.
גישה לאיבר
[עריכה]ניגשים לאיבר במילון בצורה:
<dct>[<key>]
כאשר dct הוא מילון (או שם של מילון), וkey הוא מפתח שנמצא במילון. תוצאת הביטוי הוא הערך שkey ממופה אליו במילון.
לדוגמה:
>>> grades = {'foo':80, 'bar':90}
>>> grades['foo']
80
יש להיזהר לגשת רק לאיברים שמפתחותיהם נמצאים במילון. הקוד הבא הוא שגיאה, לדוגמה:
>>> grades = {'foo':80, 'bar':90}
>>> grades['yaakov']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'yaakov'
כדי למנוע שגיאות מעין זו, השפה מאפשרת לנו לבדוק האם מפתח נמצא במילון. עושים זאת בצורה הבאה:
<key> in <dct>
כאשר key הוא מפתח וdct הוא מילון (או שם מקושר למילון). זהו ביטוי בוליאני שערכו מציין האם המפתח במילון.
לדוגמה:
>>> grades = {'foo':80, 'bar':90}
>>> 'yaakov' in grades
False
הוספת איבר
[עריכה]ניגשים לאיבר בצורה:
<dct>[<key>] = <val>
כאשר dct הוא מילון (או שם מקושר למילון), key הוא מפתח, וval הוא ערך. פקודה זו תקבע שערכו של key הוא val במילון grades. אם אין מפתח כזה במילון, הפקודה תוסיף אותו אליו. לדוגמה:
>>> grades['moshe'] = 50
תקבע שערכו של 'moshe' הוא 50 במילון grades. להלן דוגמה מלאה יותר:
>>> grades = {'foo':80, 'bar':90}
>>> grades
{'foo': 80, 'bar': 90}
>>> grades['moshe'] = 50
>>> grades
{'foo': 80, 'bar': 90, 'moshe': 50}
מחיקת איבר
[עריכה]מוחקים איבר בצורה:
del <dct>[<key>]
כאשר dct הוא מילון (או שם מקושר למילון), וkey הוא מפתח במילון. לדוגמה:
>>> del grades['moshe']
ימחק את המפתח 'moshe' מהמילון grades. להלן דוגמה מלאה יותר:
>>> grades = {'foo':80, 'bar':90}
>>> grades
{'foo': 80, 'bar': 90}
>>> grades['moshe'] = 50
>>> grades
{'foo': 80, 'bar': 90, 'moshe': 50}
>>> del grades['moshe']
>>> grades
{'foo': 80, 'bar': 90}
>>> 'moshe' in grades
False
מעבר על מפתחות וערכים
[עריכה]מעבר על מפתחות
[עריכה]אפשר להשתמש בלולאת for כדי לעבור על כל המפתחות במילון לפי הצורה:
for <var> in <dct>:
<action>
כאשר var הוא שם (שיקושר לכל אחד ממפתחות המילון), dct הוא מילון (או שם מקושר למילון), וaction היא פעולה (או בלוק). לדוגמה:
grades = {'foo': 80, 'bar': 90}
for name in grades:
print name
תדפיס את שני המפתחות שבמילון:
foo
bar
שימו לב: נשים לב שהשפה אינה אומרת דבר לגבי סדר האיברים בלולאה. אין לכתוב קוד שמניח שסדר האיברים בלולאה פועל לפי חוקיות כלשהי (לדוגמה, בסדר אלפבתי). |
מעבר על איברים
[עריכה]לפעמים רוצים לעבור בלולאה על כל איברי מילון, הן המפתחות והן הערכים.
היות שכבר ראינו שאפשר לעבור בלולאה על כל מפתחות מילון, אז מן הסתם אפשר להשתמש בכך גם לכך. הקוד הבא, לדוגמה, מדפיס כל שם והציון שאליו הוא ממופה:
grades = {'foo': 80, 'bar': 90}
for name in grades:
print 'The grade of ' + name + ' is ' + str(grades[name])
עם זאת, הקוד נחשב לא-פייתוני (הוא נחשב לא אסתטי, ובנוסף גם ידוע כלא יעיל). נוכל להשתמש בלולאה על זוגות, ולעשות זאת כך:
grades = {'foo': 80, 'bar': 90}
for (name, grade) in grades.items():
print 'The grade of ' + name + ' is ' + str(grade)
נשים לב שכדי לקבל רשימת זוגות של כל איברי מילון, אפשר לרשום:
<dct>.items()
כאשר dct הוא מילון (או שם מקושר למילון).
תקציר פונקציות מילונים
[עריכה]פונקציות פנימיות
[עריכה]dict.keys()
- מחזיר את רשימת המפתחות.dict.has_key(key_name)
- מחזיר אמת אם key_name נמצא במילון.dict.get(key_name,def_ret_val)
מחזיר את הערך של המפתח key_name, ואם הוא לא קיים במילון, מחזיר את def_ret_val.dict.items()
מחזיר רשימה של זוגות של (מפתח,ערך) בתצורה של n-יות.dict.update(other_dict)
- משלב את האיברים של other_dict ב-dict.
פונקציות חיצוניות
[עריכה]del dict[key_name]
len(dict)
- מחזיר את מספר האיברים ב-dict.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
פונקציות
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
פונקציה היא אוסף של פקודות המיועדות כולן למטרה פרטנית ומוגדרת היטב. פונקציה יכולה לקבל מידע מהתוכנית בצורת משתנים, ולהחזיר מידע לתוכנית.
הצורך בפונקציות
[עריכה]נניח שאנו כותבים תוכנית קטנה להמרת מעלות מ-Celsius ל-Fahrenheit (ראה גם כאן וכאן). התכנית תתחיל בכך שתדפיס את התרגום למעלות Fahrenheit של מעלות ה-Celsius בערכים 0, 4, 8, ..., 40, ולאחר מכן תבקש מהמשתמש מעלה ב-Celsius, ותדפיס את ערכו ב-Fahrenheit.
נרשום את התוכנית כך:
for c in range(0, 40, 4):
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = raw_input('Enter degrees in Clesius: ')
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
נוכל לשים לב שהשורה
f = 1.8 * c + 32
מופיעה פעמיים בתוכנית. זהו דבר בעייתי:
- בכל פעם שנגיע לשורה, נצטרך להיזכר מחדש מה משמעות הביטוי החשבוני.
- אם יתברר לנו ששגינו (לדוגמה, העתקנו בצורה לא נכונה את נוסחת ההמרה), נצטרך למצוא את כל המקומות בהם טעינו, ולתקן כל אחד מהם.
ככל שהתוכנית ארוכה ומסובכת יותר, הבעייתיות בדברים כאלה גדלה.
בפרק זה נלמד לפרק תוכניות לפונקציות, שכל אחת מהן מבצעת פעולה אחת מוגדרת. כך, לדוגמה, נגדיר פונקציה הממירה מעלות כך:
def celsius_to_fahrenheit(celsius):
return 1.8 * celsius + 32
הגדרת פונקציה
[עריכה]על מנת להגדיר פונקציה, יש לכתוב:
def <function_name>(<arguments>):
<body>
כאשר:
- function_name הוא שם הפונקציה.
- arguments הם ארגומנטים, כלומר משתנים שערכם נקבע מחוץ לפונקציה.
- body הוא הפקודות המתבצעות כשהפונקציה נקראת.
מייד לאחר שם הפונקציה צריכים להופיע סוגריים שבהם תכתב רשימת הפרמטרים שהפונקציה תקבל. גם אם הפונקציה לא מקבלת פרמטרים עדיין יש לכתוב את הסוגריים.
בגוף הפונקציה אפשר לכתוב כל רצף פקודות שכבר ראינו. אם הפונקציה מחזירה ערך, צריך לכתוב בגוף הפונקציה:
return <value>
כאשר value הוא הערך. אם הפונקציה אינה מחזירה ערך, אז אפשר לכתוב בכל קטע
return
דבר שיגרום ליציאה מהפונקציה.
דוגמאות
[עריכה]פונקציה עם ערך מוחזר
[עריכה]הנה הפונקציה הממירה מספר נקודה-צפה המתאר טמפרטורה ב-Celsius לטמפרטורה ב-Fahrenheit:
def celsius_to_fahrenheit(celsius):
return 1.8 * celsius + 32
הפונקציה מקבלת משתנה מסוג מספר נקודה-צפה ששמו celsius, ומחזירה מספר נקודה-צפה.
פונקציה בלי ערך מוחזר
[עריכה]הנה פונקציה המדפיסה את התרגום למעלות Fahrenheit של מעלות הCelsius בערכים 0, 4, 8, ..., 40:
def print_conversion_table():
for c in range(0, 40, 4):
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
פונקציה זו איננה מקבלת אף פרמטר, ו(בלי שום קשר) גם אינה מחזירה אף ערך.
פונקציה בלי ערך מוחזר ופקודת יציאה מפורשת
[עריכה]נניח שהחלטנו לשאול את המשתמש האם להדפיס את טבלת ההמרות, ואם המשתמש יקליד את התו 'n', לא נדפיס כלום.. נוכל לכתוב זאת כך:
def print_conversion_table_if_needed():
reply = raw_input('Print out conversion table?')
if reply == 'n':
return
for c in range(0, 40, 4):
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
בפונקציה זו, נשים לב לשורות:
if reply == 'n':
return
הפקודה return גורמת ליציאה מהפונקציה (ומחזירה None). אם הפקודה מתבצעת, אז שאר הפקודות עד סוף הפונקציה אינן מתבצעות.
קריאה לפונקציה
[עריכה]קריאה לפונקציה נכתבת כך:
<function_name>(<values>)
כאשר function_name היא שם הפונקציה, ו-values הם הערכים שיש להשים למשתניה. אם הפונקציה אינה מקבלת ארגומנטים, פשוט רושמים כך:
<function_name>()
להלן דוגמה לקריאה לפונקציה celsius_to_fahrenheit:
def celsius_to_fahrenheit(celsius):
return 1.8 * celsius + 32
f = celsius_to_fahreneit(3)
print f
השורה
f = celsius_to_fahreneit(3)
קוראת לפונקציה עם הערך 3. כעת הפונקציה מתחילה לפעול, ובתוך הפוקנציה, המשתנה celsius הוא בעל הערך 3. כשהפונקציה מגיעה לשורה
return 1.8 * celsius + 32
חוזר רצף התוכנית לשורה שקראה לה. במקרה זה, הערך המוחזר מהפונקציה יושם למשתנה f.
אם נחזור שוב לתוכנית המקורית שרשמנו בתחילת הפרק, נוכל לכתוב אותה כך:
def celsius_to_fahrenheit(celsius):
return 1.8 * celsius + 32
for c in range(0, 40, 4):
f = celsius_to_fahrenheit(c)
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = raw_input('Enter degrees in Clesius: ')
f = celsius_to_fahrenheit(c)
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
למעשה, כפי שכתובה התוכנית כעת, נוכל אפילו לוותר על חלק מהמשתנים, ולכתוב אותה בצורה קצרה יותר כך:
def celsius_to_fahrenheit(celsius):
return 1.8 * celsius + 32
for c in range(0, 40, 4):
print str(c) + ' in Celsius is ' + str( celsius_to_fahrenheit(c) ) + ' in Fahrenheit'
c = raw_input('Enter degrees in Clesius: ')
print str(c) + ' in Celsius is ' + str( celsius_to_fahrenheit(c) ) + ' in Fahrenheit'
פונקציות רקורסיביות
[עריכה]
שקלו לדלג על נושא זה מומלץ לשקול לדלג על נושא זה בפעם הראשונה בה נתקלים בו, ולחזור אליו רק לאחר מעבר כללי על כל הספר. |
פונקציה היא רקורסיבית אם היא קוראת לעצמה. לפייתון אין כללים מיוחדים לפונקציות רקורסיביות - הגדרותיהן, והקריאות להן ומהן, דומות לאלו של פונקציות לא רקורסיביות.
לדוגמה, להלן פונקציה לא רקורסיבית לחישוב עצרת:
def factorial(n):
fact = 1
for i in range(1, n+1):
fact = fact * i
return fact
ולהלן פונקציה רקורסיבית לחישוב עצרת:
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
או בצורה קצרה יותר:
def factorial(n):
return 1 if n == 0 else n * factorial(n - 1)
מעט על פונקציות והנדסת תוכנה
[עריכה]פייתון משמשת לכתיבת תוכנות מסובכות מאד. בפייתון מתמודדים עם מורכבות זו בעזרת חלוקת הקוד לפונקציות (וכן, במידה מסויימת, על ידי חלוקה למחלקות ומודולים). תכנות טוב מבוסס על חלוקת כל תוכנית למספר פונקציות, כך שלכל אחת מטרה מוגדרת אחת. כאשר פונקציה עושה יותר מדי פעולות, או כאשר קטעי קוד חוזרים על עצמם בפונקציות שונות, מחלקים את הקוד לפונקציות קטנות יותר. בצורה זו ניתן לפשט תוכנית שמבצעת משימות מורכבות לתוכנית שבה כל פונקציה לבדה מבצעת משימה פשוטה, ומורכבות התוכנית נובעת מהבנייה ההדרגתית של פונקציות אחת על השנייה. הייתרונות המושגים על ידי כך:
- הקוד נוח לקריאה וברור.
- קל יותר לשנות או לתקן כל פונקציה בנפרד, כך שאם מתגלה בעיה באחד מחלקי התוכנית מספיק לתקן רק את החלק הזה, מבלי שהדבר ישפיע על שאר חלקי התוכנית.
- הקוד מאפשר שימוש חוזר. אם קטע קוד נבדק ועובד, ואנו צריכים את אותו קטע קוד בחלק אחר של התוכנית, אין צורך לשכפל אותו.
נשתמש בקוד שראינו בצורך בפונקציות כדוגמה (למרות שזהו קוד פשוט מאד):
for c in range(0, 40, 4):
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
c = int (raw_input('Enter degrees in Clesius: '))
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
ברור למדי שהפונקציה מבצעת שני דברים: מדפיסה טבלת המרות, וממירה שאילתה בודדת. נחלק, לכן, את הקוד לפונקציות:
def print_init_conversion_table():
for c in range(0, 40, 4):
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
def handle_conversion_query():
c = int (raw_input('Enter degrees in Clesius: '))
f = 1.8 * c + 32
print str(c) + ' in Celsius is ' + str(f) + ' in Fahrenheit'
print_init_conversion_table()
handle_conversion_query()
כעת נשים לב לשורת ההמרות שחוזרת על עצמה (כפי שראינו מקודם), ונהפוך אותה לפונקציה:
def celsius_to_fahrenheit(celsius):
return 1.8 * celsius + 32
def print_init_conversion_table():
for c in range(0, 40, 4):
print str(c) + ' in Celsius is ' + str( celsius_to_fahrenheit(c) ) + ' in Fahrenheit'
def handle_conversion_query():
c = int (raw_input('Enter degrees in Clesius: '))
print str(c) + ' in Celsius is ' + str( celsius_to_fahrenheit(c) ) + ' in Fahrenheit'
print_init_conversion_table()
handle_conversion_query()
איכות הקוד כעת טובה יותר:
- הקוד חסין יותר מטעויות - צמצמנו את מספר המקומות בהם נצטרך לשנות משהו אם יש טעות בנוסחת ההמרה, לדוגמה.
- הקוד גמיש יותר - קל יהיה לשנות את הקוד אם תגיע דרישה לתוכנית שתעשה משהו אחר, לדוגמה:
- תוכנית ששואלת את המשתמש האם להדפיס טבלת המרה או לענות על שאילתה
- תוכנית שמדפיסה טבלת המרה, ואז עונה על שאילתות בלולאה עד שהמשתמש מציין שסיים.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
קלט ופלט בקבצים
חלק זה של הספר הינו קצרמר. אתם מוזמנים לתרום לוויקיספר ולערוך אותו. |
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
קריאת נתונים מתוך קובץ
[עריכה]פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
נניח כי קיים קובץ בשם results.dat אשר מכיל עמודות של מספרים, אותן ברצונכם לטעון לזיכרון. אם הפעלתם את פייתון מתוך אותה תיקייה בה נמצא הקובץ, ניתן לכתוב:
with open('results.dat') as f:
for line in f:
columns=line.split()
x=float(columns[0])
y=float(columns[1])
z=float(columns[2])
# לבצע פעולות עם הנתונים
כדאי לדעת: בכל מחזור של הלולאה, ערכיהם של x,y,z ישתנו בהתאם למספר השורה הנקראת מתוך הקובץ! במילים אחרות, x,y,z הם סקלרים, לא וקטורים. |
קריאת נתונים לתוך הזיכרון
[עריכה]במקום לקרוא מהקובץ שורה-אחר-שורה, ניתן לטעון את כל המידע לזיכרון. כך יתאפשר לבצע פעולות מורכבות, וביצוען יהיה מהיר יותר. נשנה מעט את הדוגמה הקודמת:
with open('results.dat','r') as f:
data=f.readlines()
x=[]; y=[]; z=[] # וכך הלאה, בהתאם למספר העמודות
for line in data:
columns=line.split()
x.append(float(columns[0]))
y.append(float(columns[1]))
z.append(float(columns[2]))
# לבצע פעולות עם הנתונים
במקרה זה, x,y ו-z יהיו וקטורים (מערכים). הפקודה append מוסיפה איבר למערך, וכך הוקטורים גדלים בכל מחזור של הלולאה.
כתיבת נתונים לתוך קובץ
[עריכה]הדוגמה הפשוטה ביותר לכתיבה לתוך קובץ היא:
with open('your_file_name.dat', 'w') as f:
f.write('This is a line of text\n')
הוספת מידע לקובץ
[עריכה]השימוש ב-'w'
הוא טוב כאשר אין צורך במידע שהיה מקודם בקובץ, או כאשר הקובץ לא קיים. אך אם ברצונכם להוסיף מידע, יש להשתמש ב-'a'
(מלשון append).
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מחלקות
פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
לעתים, הטיפוסים שהשפה מציעה אינם מספיקים לנו. מחלקה (class) הינה טיפוס חדש שאנו יכולים להגדיר.
הצורך במחלקות
[עריכה]עד כה השתמשנו בהשמות כגון:
>>> a=3; type(a)
<type 'int'>
>>> b=3.0; type(b)
<type 'float'>
>>> c=[3,0]; type(c)
<type 'list'>
הגדרת מחלקה - הקדמה
[עריכה]class student:
pass
מגדירים מחלקה בעזרת המילה השמורה class
def make_student(id):
s = student()
s.id = id
s.grades = {}
return s;
def update_student_grade(s, subject, grade):
s.grades[subject] = grade
def failing_student(s):
return len( [(s, g) for (s, g) in s.grades.iteritems() if g < 60] ) > 0
הגדרת מחלקה
[עריכה]class student:
def __init__(self, id):
self._id = id
self._grades = {}
s = student('233445598')
class student:
def __init__(self, id):
self._id = id
self._grades = {}
def update_grade(self, subject, grade):
self._grades[subject] = grade
class student:
def __init__(self, id):
self._id = id
self._grades = {}
def update_grade(self, subject, grade):
self._grades[subject] = grade
def failing(self):
return len( [(s, g) for (s, g) in self._grades.iteritems() if g < 60] ) > 0
s = student('233445598')
s.update_grade('heshbon', 80)
s.update_grade('handasa', 49)
עוד דוגמה
[עריכה]מה אם ברצוננו לאחסן קוארדינטות של נקודה? ומערך של קואורדינטות נקודה? ושלושה צמדי קואורדינטות שמגדירים פינות של משולש? לשם כך נגדיר "טיפוס" חדש:
class Point:
def __init__(self,x,y):
self.x=x
self.y=y
# Main:
p=Point(3.0,4.0)
print p.x,p.y
מבחינת מתכנת שמשתמש במחלקה Point, כל שעליו לעשות הוא להצהיר על משתנה מסוים כ-"Point", ולהעביר ערכים התחלתיים (לא חייבים - אפשר לאתחל מאוחר יותר).
מבחינת המחלקה, עלינו להגדיר פונקציה מיוחדת, הנקראת __init__ ובתוכה לכתוב את כל פעולות האתחול שברצוננו לבצע ברגע שבו המתכנת מצהיר על משתנה כ-Point. פונקציה מיוחדת זו נקראת פונקציה בונה (constructor).
על מנת ליצור משתנים "פנימיים", חייבים להשתמש במילה השמורה "self".
כעת נרצה להשתמש במחלקה Point כדי להגדיר את האוביקטים "ישר" ו"משולש":
class Line:
def __init__(self,p1,p2):
self.p1=p1
self.p2=p2
def Length(self):
return sqrt((self.p1.x-self.p2.x)**2 + (self.p1.y-self.p2.y)**2)
class Triangle:
def __init__(self,p1,p2,p3):
self.p1=p1
self.p2=p2
self.p3=p3
l1 = Line(self.p1,self.p2)
l2 = Line(self.p2,self.p3)
l3 = Line(self.p3,self.p1)
self.a = l1.Length()
self.b = l2.Length()
self.c = l3.Length()
def Perimeter(self):
return self.a+self.b+self.c
def Area(self):
p = 0.5*self.Perimeter() # Semiperimeter
# Heron's formula:
return sqrt(p*(p-self.a)*(p-self.b)*(p-self.c))
>>> from math import sqrt
>>> x=Point(0.0,0.0)
>>> y=Point(3.0,0.0)
>>> z=Point(3.0,4.0)
>>> T=Triangle(x,y,z)
>>> print T.Area()
6.0
כדאי לדעת: גם הרשימה (list) מוגדרת באמצעות מחלקה. |
דגש לגבי המשתנה self
[עריכה]המשתנה self עלול להיות מבלבל. זהו "מצביע" ל-instance, כלומר למופע הספציפי של מחלקה מסוימת. מספר דגשים:
- כל פונקציה רגילה במחלקה חייבת לכלול את self כפרמטר.
- כשקוראים ל'פונקצית מחלקה אין להעביר את self כפרמטר. היות שזו פונקציה ששייכת למחלקה עצמה, ולא למופעים של המחלקה, אין היא תלויה בתוכן הנתונים של מופע זה או אחר, ולכן אינה זקוקה לפרמטר self.
הרחבה לגבי מוסכמות בכתיבת מחלקות
[עריכה]מתודת הקונסטרקטור __init__
[עריכה]מתודה ה-init היא האתחול של האוביקט. מתודה זו מופעלת כל פעם שיוצרים מופע חדש של מחלקה מסוימת. ניתן, לדוגמה, ליצור מילון בשתי דרכים:
>>> d1 = dict()
>>> d1['x'] = 3; d1['y'] = 4
>>> d1
{'y': 4, 'x': 3}
>>> d2 = dict([('x',3), ('y',4)])
>>> d2
{'y': 4, 'x': 3}
במקרה הראשון, המתודה __init__ של המחלקה dict לא קיבלה אף פרמטר, ולכן יצרה מופע של מילון ריק, ואילו במקרה השני הועברה ל-init רשימה עם זוגות (key,value) אשר מהן ה-init יצר מילון עם ערכים "ראשוניים", דיפולטיביים.
משתנה התיעוד __dict__
[עריכה]המשתנה __dict__ מכיל מחרוזת תיעוד של המחלקה. ניתן להציג אותה בשתי דרכים, ישירה, ע"י גישה לתוכן המשתנה, ועקיפה, ע"י שימוש בפונקצית help הפנימית של פייתון:
>>> print list.__doc__
>>> help(list)
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
חריגים
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
חריגים בפייתון
[עריכה]חריגים הינם מחלקות מיוחדות שמאפשרות לקבל מידע במקרה של שגיאה בתכנית.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
חלק זה של הספר הינו קצרמר. אתם מוזמנים לתרום לוויקיספר ולערוך אותו. |
מודולים
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
חלוקת הקוד למודולים (קבצי קוד) מסייעת לתחזוקתו ומייעלת את בנייתו לתוכנית.
בדומה לשפת C, שם כותבים פקודת #include
, בפייתון כותבים import
.
עם זאת, בעוד ש-import פייתוני דומה מעט ל-include של C, הוא הרבה יותר מורכב ממנו. include של c מהווה פעולה טקסטואלית (שמבצע הקדם מהדר) - החלפת טקסט אחד בטקסט שני. import פייתוני למעשה ממש מריץ קוד, מעדכן namespaces, ועוד.
שקלו לדלג על נושא זה נושא זה שימושי בעיקר אם אתה כותב תוכניות גדולות. בנוסף, התוכן מניח שאתה כבר מבין את עקרונות חלוקת הקוד לפונקציות. |
הצורך במודולים
[עריכה]פייתון משמשת לכתיבת תוכנות מסובכות מאד. ברור למדי שלא ייתכן לתחזק קובץ קוד אחד ענק שיכיל מיליוני שורות קוד. הדבר היה יוצר קשיים רבים:
- קשיים אנושיים:
- לבני אדם קשה "למצוא את הידיים והרגליים" בקובץ ענק.
- בפרוייקט תוכנה מסדר גדול, סביר להניח שיותר מאדם אחד עובד על הקוד באותו פרק זמן. קובץ יחיד אינו פתרון טוב במצב כזה - רק אדם יחיד יכול לעבוד עליו בכל פרק זמן.
- בזבוז משאבי מחשב - אם כל הקוד היה מרוכז בקובץ יחיד, אז כל שינוי בקובץ היה מצריך את הידור כל הקוד מחדש.
בפרק זה נלמד כיצד לחלק את הקוד למודולים, או קבצי ותיקיות קוד שכל אחד מהם מכיל את חלקי הקוד המתאימים לנושא אחד בלבד.
ייבוא מודולים
[עריכה]לצורך הדגמה, נתבונן במספר דרכים להשתמש בפונקצית סינוס (sin). פונקצית סינוס נמצאת בתוך ספריה בשם math. פקודת היבוא הפשוטה ביותר כי כזו:
import math
math.sin(30*3.14/180)
- (התשובה שתתקבל: 0.4997701026431024)
כלומר, פקודת import בתוספת שם המודול מבצעת ייבוא "גלובלי", כך שעלינו לומר לפייתון מפורשות שעליו לחפש את הפונקציה sin בתוך מודול math.
נתבונן כעת ביבוא לוקלי:
from math import *
sin(30*3.14/180)
כלומר, פקודת import *
מייבאת באופן לוקלי את כל הפקודות שבספרית math.
אם אנו יודעים מראש כי נזדקק בתוכנית אך ורק לפונקצית הסינוס, ניתן לחסוך במשאבים על ידי כתיבת:
from math import sin
sin(30*3.14/180)
כלומר, מתבצע ייבוא לוקלי של פונקציה בודדת.
כנו כן ניתן לייבא פונקציה תחת שם אחר:
from math import sin as sinus
sinus(30*3.14/180)
על מנת לראות את כל הפקודות של מודול מסוים, יש להשתמש בפקודה dir:
>>> import cmath
>>> for func in dir(cmath):
... print func
...
__doc__
__file__
__name__
acos
acosh
asin
asinh
atan
atanh
cos
cosh
e
exp
log
log10
pi
sin
sinh
sqrt
tan
tanh
ראו גם
[עריכה]- גישה וקטורית למערכים באמצעות NumPy
- אנליזה נומרית עם SciPy
- ספרית הגרפיקה Matplotlib
- המודול os
- המודול sys
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
קבצי אצווה
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
קובץ אצווה
הוא קובץ המכיל סדרת פקודות למערכת ההפעלה. אפשר להשתמש בקבצי אצווה, לדוגמה, למטלות תחזוק-מערכת שונות, לדוגמה ניהול גרסאות או גיבוי. פייתון, כשפת דבק, מתאימה במיוחד לכתיבת קבצי אצווה מתוחכמים (ראו לדוגמה את התוכנה החופשית mercurial לניהול גרסאות).
דוגמה רצה
[עריכה]נרצה לכתוב תוכנית add.py
המקבלת שני מספרים, ומדפיסה את סכומם. בחלון הפקודות, המשתמש יוכל להשתמש בה כך:
add.py 2 3
5
add.py 1 1
2
הבעיות שאותן נפתור
[עריכה]בכתיבת קובץ אצווה יש שתי בעיות מיוחדות שאינן קיימות לרוב בתוכניות רגילות. נעבור עליהן כאן.
הפעלה כפקודת מערכת
[עריכה]כדי להעתיק קובץ בשם foo לקובץ בשם bar, אפשר לפתוח חלון פקודות, ולכתוב פקודה מתאימה. במערכת לינוקס, לדוגמה, אפשר לכתוב:
cp foo bar
ובמערכת חלונות אפשר לכתוב
copy foo bar
עד עתה ראינו בספר תוכניות שאפשר להריצן מחלון הפקודות כך:
python add.py 2 3
5
כלומר, המשתמשים מבקשים ממערכת ההפעלה להריץ את python על הקובץ add.py
. בכתיבת קובץ אצווה, עם זאת, נרצה שיהיה אפשר לכתוב כך:
add.py 2 3
5
כלומר, המשתמשים מבקשים ממערכת ההפעלה להריץ את קובץ האצווה add.py
שרק במקרה כתוב בפייתון. איננו רוצים להכריח את המשתמשים להריץ במודע את python, או אפילו לדעת מה השפה בה נכתב קובץ האצווה. למעשה, יכולנו לקרוא לקובץ האצווה add, ולהריצו כך:
add 2 3
5
העברת פרמטרים לתוכנית
[עריכה]כבר ראינו שאפשר להעביר פרמטרים לפונקציות. באופן דומה, המשתמשים יכולים להעביר פרמרטרים לתוכניות שלמות.
לדוגמה, כאשר כותבים
cp foo bar
או
copy foo bar
אז foo
וbar
מועברות לתוכנית.
באותו אופן, כאשר כותבים
add.py 2 3
5
אז יש להעביר את 2
ו3
לתוכנית. בפרק זה נראה כיצד פייתון מאפשרת זאת.
החזרת סטטוס למערכת ההפעלה
[עריכה]שבנג!
[עריכה]#!/usr/bin/env python
מציאת מספר הפרמטרים
[עריכה]המשתנה sys.argc
מתאר את מספר הפרמטרים שהעביר המשתמש ועוד אחת (מסיבות היסטוריות, גם שם התוכנית נחשבת פרמטר). כך, לדוגמה, אם המשתמש הקליד
add.py 2 3
אז sys.argc
הוא 3.
נתחיל בבדיקה שקיבלנו את מספר המשתנים הנכון:
#!/usr/bin/env python
import sys
def usage():
print 'usage: add.py <num1> <num2>'
if sys.argc != 3
usage()
sys.exit(-1)
הפונקציה usage
מדפיסה את צורת השימוש הנכונה בפונקציה. לאחר שבונים אותה, בודקים אם מספר הפרמטרים תקין. אם לא, קוראים לפונקציה, ולאחר מכן יוצאים מהתוכנית. השורה
sys.exit(-1)
מסיימת את התוכנית, ומודיעה למערכת ההפעלה שארעה בעיה (במקרה זה, ניסיון להשתמש בתוכנית שלא כתכנונה). לא נתעמק בכך כעת.
גישה לפרמרטרים
[עריכה]הפרמטרים נמצאים כולם ברשימה בשם sys.argv
. כאמור, האיבר הראשון הוא פשוט שם התוכנית. נשים לב שאיברי הרשימה הם כולם מחרוזות. כלומר, אם המשתמש הקליד
add.py 2 3
אז sys.argv
הנו הרשימה:
['add.py', '2', '3']
כפי שראינו, נצטרך להמיר את המחרוזות - לדוגמה נצטרך להמיר את המחרוזת '2'
למספר 2
. נעשה זאת כך
num1 = float(sys.argv[1])
num2 = float(sys.argv[2])
כל שנותר הוא להדפיס את התוצאה:
print num1 + num2
להלן קובץ האצווה עד כה.
#!/usr/bin/env python
import sys
def usage():
print 'usage: add.py <num1> <num2>'
if sys.argc != 3
usage()
sys.exit(-1)
num1 = float(sys.argv[1])
num2 = float(sys.argv[2])
print num1 + num2
טיפול בקלטים שגויים
[עריכה]#!/usr/bin/env python
import sys
def usage():
print 'usage: add.py <num1> <num2>'
if sys.argc != 3
usage()
sys.exit(-1)
try:
num1 = float(sys.argv[1])
num2 = float(sys.argv[2])
except:
usage()
sys.exit(-1)
print num1 + num2
ראו גם
[עריכה]
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
הספריה הסטנדרטית
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
פרק זה לוקה בחסר. אתם מוזמנים לתרום לוויקיספר ולהשלים אותו. ראו פירוט בדף השיחה.
פייתון מאפשרת שימוש בספריות - קבצים המכילים קטעי קוד המוכנים לשימוש. אנו נתמקד בפרט בספריה הסטנדרטית, המותקנת יחד עם המתרגם. זוהי ספריה אדירת מימדים, ונכסה חלק מזערי ביותר בה.
יש ספריות שמותקנות יחד עם המתרגם. פייתון מחזיקה בפילוסופיית "הבטריות בפנים" - כלומר שכל מה שצריך נמצא שם. זו עמדה שנויה במחלוקת (די הפוכה מזו של כותבי הספרייות הסטנדרטיות בC++, לדוגמה). מכל מקום, זו ספריה שאפתנית ואדירת מימדים, והיא מכילה מספר רב של תתי ספריות שכל אחת מהן יכולה להצדיק ספר שלם.
צעדי השימוש בספריות
[עריכה]כאשר כותבים קוד, לפעמים מזהים צורך בפעולה מועילה שכיחה למדי - שכיחה במידה כזו שייתכן שהיא חלק מספרייה. להלן מספר פעולות שסביר להניח שאינך הראשון שנדרש להן:
- השוואה בין שתי מחרוזות
- חישוב הפונקציה הטריגונומטרית סינוס
- הדפסת הזמן בשעון המחשב
אם זה המצב, כדאי להשתמש בספריה אם אפשר. כדי להשתמש בספריה, יש צורך בפעולות הבאות:
- מציאת הספריה המתאימה
- הוספת פקודה לטעינת הספריה
בקוד עצמו אפשר להשתמש בפונקציות ומחלקות הספריה בצורה רגילה לחלוטין.
מציאת הספריה המתאימה
[עריכה]ראשית עליך למצוא את הספריה המתאימה לפעולה שאתה מחפש. אין דרך מסודרת לעשות זאת (ייתכן שתיאלץ לחפש באינטרנט, לדוגמה). בפרק זה נתמקד מכל מקום רק בספריה אחת - הספריה הסטנדרטית המגיעה עם המתרגם.
הפקודה לטעינת הספריה
[עריכה]==import==
import היא פקודה אשר משמשת להוספת ספריות כיוון שפייתון מורכבת מפקודות שבאות מובנות ועם הרבה ספריות וכדי לא ליצור עומס על המחשב. בכדי להקל היוצרים של פייתון הוסיפו פקודה שמוסיפה ספרייה במקום לעשות זאת על ידי תוכנות חיצניות
הפקודה import, שאותה ראינו בפייתון/פייתון גרסה 2/מודולים. הפקודה import בעצם נותנת לנו רשות לקרוא לספריה. דוגמא: import sys
sys זהו שם של ספרייה הנקראת system.
דוגמה: חישוב סינוס
[עריכה]נניח שאנו רוצים לקלוט מעלה (ברדיאנים) מהמשתמש, ולחשב את הסינוס שלו. פייתון איננה כוללת פקודה מיוחדת לחישוב סינוס (או כל פונקציה טריגונומטרית אחרת), אך כבר ראינו שהשפה כוללת פעולות חשבוניות. נוכל להשתמש בטור טיילור, לכן, כפי שעשינו בתרגיל קירוב סינוס על ידי טור טיילור. הנה הפיתרון המופיע שם, המתבסס על קירוב ע"י 10 האיברים הראשונים בטור:
sign = 1
factorial = 1
angle = float(raw_input('Please enter angle: '))
power = angle;
sinus = 0
for i in range(10):
sinus += sign * power / factorial
sign = -sign
factorial *= (2 * i + 2) * (2 * i + 3)
power *= angle ** 2
print 'sin(%f) ~= %f\n' % (angle, sinus)
פיתרון זה מצריך אותנו לבדוק מהו טור טיילור המתאים ולקודד אותו, פעולה בעלת סיכוי לא-זניח לשגיאות. יותר מכך, הפיתרון המופיע כאן אינו מושלם:
- מדוע החלטנו להשתמש דווקא ב10 איברים?
- מה בכלל ערך השגיאה? האם לקחנו בחשבון שערך השגיאה גדל יחד עם המעלה הנקלטת (בערך מוחלט)?
- האם כלל השתמשנו במחזוריות סינוס?
מובן שאפשר למצוא פתרון מתוחכם קצת יותר, אך ככל שנתחכם יותר, כך גדל הסיכוי שנבזבז זמן בכתיבה ובתיקון. זה מיותר, מפני שסביר להניח שאיננו הראשונים להזדקק לסינוס בפייתון.
במקום זאת נשתמש בספריה הסטנדרטית. נחפש [[1]] מהו קובץ הכותרת המתאים. ניחוש הגיוני הוא math.h. עיון בתיעוד שלו מלמד שאכן יש בו פונקציית סינוס. נשתמש בה, לכן:
import math
angle = raw_input('Please enter angle: ')
print 'sin(%f) ~= %f\n' % (angle, math.sin(angle) )
זוהי אלטרנטיבה קצרה ובטוחה יותר.
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
הרחבות בעזרת שפות נמוכות יותר
פייתון/פייתון גרסה 2/הרחבות בעזרת שפות נמוכות יותר
תכנות מקבילי
חלק זה של הספר הינו קצרמר. אתם מוזמנים לתרום לוויקיספר ולערוך אותו. |
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
הרצת פקודה ברקע התוכנית
[עריכה]
שקלו לדלג על נושא זה סעיף זה עוסק ב־ |
כידוע, תוכנית מחשב מכילה פקודות לביצוע סדרתי, והפקודה הבאה לא תבוצע לפני תום הפקודה הנוכחית. אך כאשר מריצים תוכנות חיצוניות (באמצעות os.system
) המצב שונה, מכיוון שאפשר לבקש ממערכת ההפעלה לטפל במקביליות. בשורת הפקודה דבר זה נעשה על ידי הפקודה start בחלונות והאופרטור & ביוניקס/לינוקס.
אם לדוגמה ברצונכם להפעיל את דפדפן פיירפוקס, תוך המשכת התוכנית שלכם, ניתן לעשות זאת באמצעות:
#!/usr/bin/env python
import sys
import os
app='firefox'
if sys.platform.startswith('win'):
command='start ' + app
elif os.name=='posix ':
command=app + ' &'
os.system(command)
# rest of your code...
הרצת פונקציות מקביליות
[עריכה]import thread
def loop_and_print(msg):
for i in range(1,10):
print msg
thread.start_new_thread(loop_and_print, ('hello',))
thread.start_new_thread(loop_and_print, ('hello',))
import thread
def loop_and_print(msg, num):
for i in range(1,num):
print msg
thread.start_new_thread(loop_and_print, ('hello', 1000))
נעילות
[עריכה]import thread
import threading
l = threading.Lock()
def loop_and_print(msg):
for i in range(1,10000):
l.acquire()
print msg
l.release()
thread.start_new_thread(loop_and_print, ('hello'))
thread.start_new_thread(loop_and_print, ('world'))
קישורים חיצוניים
[עריכה]נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
שימוש בשקעים
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2
מהם שקעים?
[עריכה]שקעים (בלועזית: sockets) הם למעשה הדרך הבסיסית ביותר ליצור תקשורת אינטרנט - כל יישום המתחבר לאינטרנט, החל מדפדפן ועד יישומי שורת־פקודה, כמו ping.
שימוש בשקעים בפייתון
[עריכה]לפייתון ספריית קוד פשוטה לשימוש בשם socket. לתחילת העבודה, יש לייבא את ספריית השקעים כך:
import socket
כך יוצרים עצם מסוג שקע שיתמש ב IPv4 ובפרוטוקול TCP:
conn = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
לעצם מסוג שקע בפרוטוקול UDP:
conn = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
לאחר מכן, ישנן שתי אפשרויות:
- אם רוצים לבנות שרת (תוכנה שמשרתת תוכנות אחרות הנקראות בדרך־כלל "לקוחות") יש להזין את הקוד הבא:
conn.bind(('',port))
הפונקציה bind מקבלת touple, ומקשרת בין הפורט (מפתח) הרצוי לבין ה ip כדי לקבל חיבורים ולהעביר מידע במפתח זה.
- אם מעוניינים לבנות לקוח (תוכנה שמתחברת לשרת כדי להשתמש בשירותים שהוא מציע) יש להזין את הקוד הבא:
conn.connect((ip,port))
בשני המקרים, ip הוא הכתובת שאליה רוצים להתחבר (לקוח בלבד) ואילו port הוא הפתחה. לאחר מכן, על מנת לשלוח נתונים, יש להשתמש בפונקציה send של עצם השקע שיצרנו:
conn.send('DATA\r\n')
הפקודה הזו תשתמש בעצם conn ותשלח את המחרוזת DATA. אם מעוניינים לקבל מידע, ניתן לעשות זאת באמצעות לולאה אין-סופית:
while True:
data = conn.recv(4096)
לאחר שסיימנו לשלוח, לקבל ולעבד את המידע, נוכל לסגור את החיבור:
conn.close()
שיטות מתקדמות
[עריכה]לשיטה הבסיסית שלמדנו ישנם מספר חסרונות:
- ניתן להאזין לתעבורה ובכך לחשוף מידע, שבמקרים מסוימים עלול להיות רגיש ביותר.
- הליך קבלת המידע הוא סנכרוני, כלומר התכנה שכתבנו תוכל לקבל מידע רק אחרי שהיא סיימה לעבד את המידע הקיים.
- כתיבת שרת או לקוח דורשת בקיאות בפרוטוקול ולוקחת לא מעט שורות קוד.
מסיבות אלו, כדאי להשתמש בשיטות אחרות:
- שימוש ב־asyncore
- שימוש ב־ssl(ניתן לשלב עם ספריות אחרות).
- שימוש בספרייה http://twistedmatrix.com.
- שימוש בספרייה של הפרוטוקול הספציפי שאנו רוצים לעבוד עמו.
שימוש ב־asyncore
[עריכה]הספרייה asyncore נכללת עם המפרש ואין צורך בהתקנתה. כדי ליצור לקוח באמצעותה, יש צורך תחילה לייבא את הספרייה socket וליצור מחלקה שמתבססת על asyncore.dispatcher ולהוסיף בפונקציה __init__ את השורות הבאות:
asyncore.dispatcher.__init__(self) # אתחול מחלקת הבסיס
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) # יצירת אובייקט מסוג שקע
self.connect((host, port)) # התחברות לשרת
self.buffer = [] # יצירת מערך שמכיל את המידע שמתקבל
נמצאה תבנית הקוראת לעצמה: תבנית:פייתון/פייתון גרסה 2 לאחר מכן, ניתן להוסיף את הפונקציות הבאות כדי לטפל באירועים שונים של הלקוח:
- התחברות מוצלחת לשרת - handle_connect
- התנתקות מהשרת - handle_close
- קבלת מידע מהשרת - handle_read
- זיהוי שקע שניתן לשלוח בו מידע לשרת - handle_write