منابع ترجمه · The Python Tutorial · فصل ۳
مقدمهای غیررسمی بر پایتون (آموزش رسمی پایتون، فصل ۳)
منبع اصلی: The Python Tutorial, Chapter 3: An Informal Introduction to Python — Python Software Foundation
💡 این صفحه مثل یک نوتبوک Jupyter است: متغیر و تابعی که در یک سلول تعریف شود، در سلولهای بعدی همین صفحه در دسترس است. سلولها را به ترتیب اجرا کنید، یا با «⏮ تا اینجا» همهٔ سلولهای قبلیِ اجرانشده را یکجا اجرا کنید.
در مثالهای زیر، ورودی و خروجی با وجود یا نبود اعلانها (>>> و ...) از هم تشخیص داده میشوند: برای تکرار مثال، هر چیزی را که بعد از اعلان میآید، هنگامی که اعلان ظاهر میشود باید تایپ کنید؛ خطوطی که با اعلان شروع نمیشوند خروجی مفسر هستند. توجه کنید که یک اعلان ثانویه که بهتنهایی روی یک خط در مثال بیاید یعنی باید یک خط خالی تایپ کنید؛ این برای پایان دادن به یک فرمان چندخطی استفاده میشود.
میتوانید از دکمهٔ «Copy» (هنگام نگه داشتن نشانگر روی یک نمونهکد یا لمس آن، در گوشهٔ بالا-راست ظاهر میشود) استفاده کنید که اعلانها را حذف میکند و خروجی را کنار میگذارد، تا خطوط ورودی را در مفسر خود کپی و جایگذاری کنید.
بسیاری از مثالهای این راهنما، حتی مثالهایی که در اعلان تعاملی وارد میشوند، شامل توضیحات (comments) هستند. توضیحات در پایتون با نویسهٔ هش، #، شروع میشوند و تا پایان خط فیزیکی ادامه مییابند. یک توضیح میتواند در ابتدای خط یا بعد از فضای خالی یا کد بیاید، اما درون یک لیترال رشتهای نه. نویسهٔ هش درون یک لیترال رشتهای فقط یک نویسهٔ هش است. چون توضیحات برای روشنتر کردن کد هستند و پایتون آنها را تفسیر نمیکند، هنگام تایپ مثالها میتوان آنها را حذف کرد.
چند نمونه:
# this is the first comment
spam = 1 # and this is the second comment
# ... and now a third!
text = "# This is not a comment because it's inside quotes."
۳٫۱. استفاده از پایتون بهعنوان ماشینحساب
بیایید چند فرمان ساده در پایتون را امتحان کنیم. مفسر را راهاندازی کنید و منتظر اعلان اصلی، >>>، بمانید. (نباید زمان زیادی ببرد.)
۳٫۱٫۱. اعداد
مفسر مانند یک ماشینحساب ساده عمل میکند: میتوانید یک عبارت در آن تایپ کنید و مقدار را مینویسد. نحو عبارتها سرراست است: عملگرهای +، -، * و / برای محاسبات حسابی به کار میروند؛ از پرانتز (()) میتوان برای گروهبندی استفاده کرد. برای مثال:
>>> 2 + 2
4
>>> 50 - 5*6
20
>>> (50 - 5*6) / 4
5.0
>>> 8 / 5 # division always returns a floating-point number
1.6
اعداد صحیح (مثلاً 2، 4، 20) نوع int دارند و اعدادی که بخش کسری دارند (مثلاً 5.0، 1.6) نوع float. در ادامهٔ آموزش دربارهٔ انواع عددی بیشتر خواهیم دید.
تقسیم (/) همیشه یک float برمیگرداند. برای انجام تقسیم صحیح (floor division) و گرفتن نتیجهٔ صحیح میتوانید از عملگر // استفاده کنید؛ برای محاسبهٔ باقیمانده میتوانید از % استفاده کنید:
>>> 17 / 3 # classic division returns a float
5.666666666666667
>>>
>>> 17 // 3 # floor division discards the fractional part
5
>>> 17 % 3 # the % operator returns the remainder of the division
2
>>> 5 * 3 + 2 # floored quotient * divisor + remainder
17
در پایتون میتوان با عملگر ** توانها را محاسبه کرد [۱]:
>>> 5 ** 2 # 5 squared
25
>>> 2 ** 7 # 2 to the power of 7
128
علامت مساوی (=) برای نسبت دادن یک مقدار به یک متغیر به کار میرود. پس از آن، پیش از اعلان تعاملی بعدی هیچ نتیجهای نمایش داده نمیشود:
>>> width = 20
>>> height = 5 * 9
>>> width * height
900
اگر متغیری «تعریف» نشده باشد (مقداری به آن نسبت داده نشده باشد)، تلاش برای استفاده از آن خطا میدهد:
>>> n # try to access an undefined variable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined
پشتیبانی کامل از ممیز شناور وجود دارد؛ عملگرهایی که عملوندهایشان انواع مختلط هستند، عملوند صحیح را به ممیز شناور تبدیل میکنند:
>>> 4 * 3.75 - 1
14.0
در حالت تعاملی، آخرین عبارت چاپشده به متغیر _ نسبت داده میشود. یعنی وقتی از پایتون بهعنوان ماشینحساب رومیزی استفاده میکنید، ادامهٔ محاسبات تا حدی آسانتر است، مثلاً:
>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06
کاربر باید با این متغیر مانند یک متغیر فقطخواندنی رفتار کند. بهطور صریح به آن مقدار نسبت ندهید — چنین کاری یک متغیر محلی مستقل با همان نام ایجاد میکند که متغیر درونساخت و رفتار جادویی آن را پنهان میکند.
علاوه بر int و float، پایتون انواع دیگر اعداد را هم پشتیبانی میکند، مانند Decimal و Fraction. پایتون همچنین پشتیبانی درونساخت از اعداد مختلط دارد و از پسوند j یا J برای نشان دادن بخش موهومی استفاده میکند (مثلاً 3+5j).
۳٫۱٫۲. متن
پایتون میتواند علاوه بر اعداد، متن را هم دستکاری کند (که با نوع str نمایش داده میشود و به آن «رشته» (string) میگویند). این شامل نویسههایی مانند «!»، کلمههایی مانند «rabbit»، نامهایی مانند «Paris»، جملههایی مانند «Got your back.»، «Yay! :)» و غیره میشود. آنها را میتوان درون گیومهٔ تکی ('...') یا گیومهٔ جفت ("...") با نتیجهٔ یکسان قرار داد [۲].
>>> 'spam eggs' # single quotes
'spam eggs'
>>> "Paris rabbit got your back :)! Yay!" # double quotes
'Paris rabbit got your back :)! Yay!'
>>> '1975' # digits and numerals enclosed in quotes are also strings
'1975'
برای اینکه خود نویسهٔ گیومه را درون رشته بیاوریم، باید آن را با گذاشتن \ پیش از آن «escape» کنیم. یا میتوانیم از نوع دیگر گیومه استفاده کنیم:
>>> 'doesn\'t' # use \' to escape the single quote...
"doesn't"
>>> "doesn't" # ...or use double quotes instead
"doesn't"
>>> '"Yes," they said.'
'"Yes," they said.'
>>> "\"Yes,\" they said."
'"Yes," they said.'
>>> '"Isn\'t," they said.'
'"Isn\'t," they said.'
در شل پایتون، تعریف رشته و رشتهٔ خروجی ممکن است متفاوت به نظر برسند. تابع print() با حذف گیومههای دورِ رشته و چاپ نویسههای escapeشده و ویژه، خروجی خواناتری تولید میکند:
>>> s = 'First line.\nSecond line.' # \n means newline
>>> s # without print(), special characters are included in the string
'First line.\nSecond line.'
>>> print(s) # with print(), special characters are interpreted, so \n produces new line
First line.
Second line.
اگر نمیخواهید نویسههایی که پیش از آنها \ آمده بهعنوان نویسهٔ ویژه تفسیر شوند، میتوانید با افزودن r پیش از گیومهٔ اول از رشتههای خام (raw strings) استفاده کنید:
>>> print('C:\this\name') # here \t means tab, \n means newline
C: his
ame
>>> print(r'C:\this\name') # note the r before the quote
C:\this\name
یک نکتهٔ ظریف دربارهٔ رشتههای خام وجود دارد: یک رشتهٔ خام نمیتواند به تعداد فرد نویسهٔ \ ختم شود؛ برای اطلاعات بیشتر و راهحلها به مدخل پرسشهای متداول نگاه کنید.
لیترالهای رشتهای میتوانند چند خط را در بر بگیرند. یک راه، استفاده از سهگیومه است: """...""" یا '''...'''. نویسههای پایان خط بهطور خودکار در رشته گنجانده میشوند، اما با افزودن \ در انتهای خط میتوان از آن جلوگیری کرد. در مثال زیر، خط جدید ابتدایی گنجانده نمیشود:
>>> print("""\
... Usage: thingy [OPTIONS]
... -h Display this usage message
... -H hostname Hostname to connect to
... """)
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
>>>
رشتهها را میتوان با عملگر + به هم متصل (concatenate) کرد و با * تکرار نمود:
>>> # 3 times 'un', followed by 'ium'
>>> 3 * 'un' + 'ium'
'unununium'
دو یا چند لیترال رشتهای (یعنی آنهایی که بین گیومهها قرار دارند) که کنار هم بیایند، بهطور خودکار به هم متصل میشوند.
>>> 'Py' 'thon'
'Python'
این ویژگی وقتی خاصاً مفید است که بخواهید رشتههای بلند را بشکنید:
>>> text = ('Put several strings within parentheses '
... 'to have them joined together.')
>>> text
'Put several strings within parentheses to have them joined together.'
اما این فقط با دو لیترال کار میکند، نه با متغیرها یا عبارتها:
>>> prefix = 'Py'
>>> prefix 'thon' # can't concatenate a variable and a string literal
File "<stdin>", line 1
prefix 'thon'
^^^^^^
SyntaxError: invalid syntax
>>> ('un' * 3) 'ium'
File "<stdin>", line 1
('un' * 3) 'ium'
^^^^^
SyntaxError: invalid syntax
اگر میخواهید متغیرها یا یک متغیر و یک لیترال را به هم متصل کنید، از + استفاده کنید:
>>> prefix + 'thon'
'Python'
رشتهها را میتوان اندیسگذاری (indexing/subscripting) کرد، بهطوری که اولین نویسه اندیس ۰ دارد. نوع نویسهٔ جداگانهای وجود ندارد؛ یک نویسه صرفاً رشتهای به اندازهٔ یک است:
>>> word = 'Python'
>>> word[0] # character in position 0
'P'
>>> word[5] # character in position 5
'n'
اندیسها میتوانند منفی هم باشند تا شمارش از راست شروع شود:
>>> word[-1] # last character
'n'
>>> word[-2] # second-last character
'o'
>>> word[-6]
'P'
توجه کنید که چون -0 همان 0 است، اندیسهای منفی از -1 شروع میشوند.
علاوه بر اندیسگذاری، برش (slicing) هم پشتیبانی میشود. در حالی که اندیسگذاری برای گرفتن نویسههای منفرد به کار میرود، برش به شما اجازه میدهد یک زیررشته بگیرید:
>>> word[0:2] # characters from position 0 (included) to 2 (excluded)
'Py'
>>> word[2:5] # characters from position 2 (included) to 5 (excluded)
'tho'
اندیسهای برش مقادیر پیشفرض مفیدی دارند؛ اندیس اول حذفشده بهطور پیشفرض صفر است، و اندیس دوم حذفشده بهطور پیشفرض اندازهٔ رشتهای است که برش میخورد.
>>> word[:2] # character from the beginning to position 2 (excluded)
'Py'
>>> word[4:] # characters from position 4 (included) to the end
'on'
>>> word[-2:] # characters from the second-last (included) to the end
'on'
توجه کنید که چگونه ابتدا همیشه گنجانده میشود و انتها همیشه کنار گذاشته میشود. این تضمین میکند که s[:i] + s[i:] همیشه با s برابر است:
>>> word[:2] + word[2:]
'Python'
>>> word[:4] + word[4:]
'Python'
یک راه برای به یاد آوردن نحوهٔ کار برشها این است که اندیسها را مانند اشارهگرهایی بین نویسهها در نظر بگیرید، بهطوری که لبهٔ چپ اولین نویسه شمارهٔ ۰ دارد. آنگاه لبهٔ راست آخرین نویسهٔ یک رشتهٔ n نویسهای اندیس n دارد، برای مثال:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
ردیف اول اعداد، موقعیت اندیسهای ۰…۶ را در رشته نشان میدهد؛ ردیف دوم اندیسهای منفیِ متناظر را. برشِ i تا j شامل همهٔ نویسههای بین لبههای برچسبخورده با i و j است.
برای اندیسهای نامنفی، طول یک برش برابر تفاضل اندیسهاست، به شرط آنکه هر دو در محدوده باشند. برای مثال طول word[1:3] برابر ۲ است.
تلاش برای استفاده از اندیسی که بیش از حد بزرگ است، خطا میدهد:
>>> word[42] # the word only has 6 characters
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: string index out of range
اما اندیسهای برشِ خارج از محدوده، هنگام برشدادن بهظرافت مدیریت میشوند:
>>> word[4:42]
'on'
>>> word[42:]
''
رشتههای پایتون قابلتغییر نیستند — آنها تغییرناپذیر (immutable) هستند. بنابراین نسبت دادن به یک موقعیت اندیسگذاریشده در رشته خطا میدهد:
>>> word[0] = 'J'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> word[2:] = 'py'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
اگر به رشتهٔ متفاوتی نیاز دارید، باید رشتهٔ جدیدی بسازید:
>>> 'J' + word[1:]
'Jython'
>>> word[:2] + 'py'
'Pypy'
تابع درونساخت len() طول یک رشته را برمیگرداند:
>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34
همچنین ببینید
نوع دنبالهٔ متنی — str: رشتهها نمونههایی از انواع دنباله (sequence types) هستند و عملیات مشترکی را که این انواع پشتیبانی میکنند، دارند.
متدهای رشته: رشتهها تعداد زیادی متد برای تبدیلها و جستوجوهای پایه دارند.
f-strings: لیترالهای رشتهای که عبارتهای تعبیهشده دارند.
نحو رشتهٔ قالببندی: اطلاعاتی دربارهٔ قالببندی رشته با
str.format().قالببندی رشته به سبک printf: عملیات قدیمی قالببندی که وقتی رشتهها عملوند چپ عملگر
%باشند فراخوانی میشوند، در اینجا با جزئیات بیشتری شرح داده شدهاند.
۳٫۱٫۳. فهرستها
پایتون تعدادی نوع دادهٔ مرکب (compound) میشناسد که برای گروهبندی مقادیر دیگر به کار میروند. همهکارهترین آنها فهرست (list) است که میتوان آن را بهصورت فهرستی از مقادیر (آیتمها) جداشده با ویرگول بین کروشهها نوشت. فهرستها ممکن است آیتمهایی از انواع مختلف داشته باشند، اما معمولاً همهٔ آیتمها نوع یکسانی دارند.
>>> squares = [1, 4, 9, 16, 25]
>>> squares
[1, 4, 9, 16, 25]
مانند رشتهها (و همهٔ انواع دنبالهٔ درونساخت دیگر)، فهرستها را میتوان اندیسگذاری و برش داد:
>>> squares[0] # indexing returns the item
1
>>> squares[-1]
25
>>> squares[-3:] # slicing returns a new list
[9, 16, 25]
فهرستها عملیاتی مانند اتصال را هم پشتیبانی میکنند:
>>> squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
بر خلاف رشتهها که تغییرناپذیر هستند، فهرستها نوعی تغییرپذیر (mutable) هستند، یعنی میتوان محتوای آنها را تغییر داد:
>>> cubes = [1, 8, 27, 65, 125] # something's wrong here
>>> 4 ** 3 # the cube of 4 is 64, not 65!
64
>>> cubes[3] = 64 # replace the wrong value
>>> cubes
[1, 8, 27, 64, 125]
همچنین میتوانید با استفاده از متد list.append() آیتمهای جدیدی به انتهای فهرست اضافه کنید (دربارهٔ متدها بعداً بیشتر خواهیم دید):
>>> cubes.append(216) # add the cube of 6
>>> cubes.append(7 ** 3) # and the cube of 7
>>> cubes
[1, 8, 27, 64, 125, 216, 343]
انتساب ساده در پایتون هرگز دادهٔ جدید کپی نمیکند. وقتی یک فهرست را به یک متغیر نسبت میدهید، متغیر به همان فهرست موجود ارجاع میدهد. هر تغییری که از طریق یک متغیر به فهرست بدهید، از طریق همهٔ متغیرهای دیگری که به آن ارجاع میدهند دیده میشود:
>>> rgb = ["Red", "Green", "Blue"]
>>> rgba = rgb
>>> id(rgb) == id(rgba) # they reference the same object
True
>>> rgba.append("Alph")
>>> rgb
["Red", "Green", "Blue", "Alph"]
همهٔ عملیات برش، فهرست جدیدی شامل عناصر درخواستشده برمیگردانند. این یعنی برش زیر یک کپی سطحی (shallow copy) از فهرست برمیگرداند:
>>> correct_rgba = rgba[:]
>>> correct_rgba[-1] = "Alpha"
>>> correct_rgba
["Red", "Green", "Blue", "Alpha"]
>>> rgba
["Red", "Green", "Blue", "Alph"]
انتساب به برشها هم ممکن است و حتی میتواند اندازهٔ فهرست را تغییر دهد یا آن را کاملاً خالی کند:
>>> letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> letters
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> # replace some values
>>> letters[2:5] = ['C', 'D', 'E']
>>> letters
['a', 'b', 'C', 'D', 'E', 'f', 'g']
>>> # now remove them
>>> letters[2:5] = []
>>> letters
['a', 'b', 'f', 'g']
>>> # clear the list by replacing all the elements with an empty list
>>> letters[:] = []
>>> letters
[]
تابع درونساخت len() برای فهرستها هم کاربرد دارد:
>>> letters = ['a', 'b', 'c', 'd']
>>> len(letters)
4
میتوان فهرستها را تودرتو کرد (فهرستهایی ساخت که فهرستهای دیگر را در خود دارند)، برای مثال:
>>> a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'
۳٫۲. نخستین گامها به سوی برنامهنویسی
البته میتوانیم از پایتون برای کارهای پیچیدهتر از جمع دو با دو استفاده کنیم. برای مثال، میتوانیم زیردنبالهٔ آغازین دنبالهٔ فیبوناچی را به این شکل بنویسیم:
>>> # Fibonacci series:
>>> # the sum of two elements defines the next
>>> a, b = 0, 1
>>> while a < 10:
... print(a)
... a, b = b, a+b
...
0
1
1
2
3
5
8
این مثال چند ویژگی جدید را معرفی میکند.
-
خط اول شامل یک انتساب چندگانه (multiple assignment) است: متغیرهای
aوbهمزمان مقادیر جدید ۰ و ۱ را میگیرند. در آخرین خط دوباره از آن استفاده شده، که نشان میدهد عبارتهای سمت راست همگی پیش از انجام هر انتسابی ارزیابی میشوند. عبارتهای سمت راست از چپ به راست ارزیابی میشوند. -
حلقهٔ
whileتا زمانی که شرط (اینجا:a < 10) درست باقی بماند اجرا میشود. در پایتون، مانند C، هر مقدار صحیح ناصفر درست است؛ صفر نادرست است. شرط میتواند یک رشته یا فهرست هم باشد، در واقع هر دنبالهای؛ هر چیزی که طولش ناصفر باشد درست است و دنبالههای خالی نادرستاند. آزمونی که در این مثال استفاده شده یک مقایسهٔ ساده است. عملگرهای مقایسهٔ استاندارد مانند C نوشته میشوند:<(کوچکتر)،>(بزرگتر)،==(مساوی)،<=(کوچکتر یا مساوی)،>=(بزرگتر یا مساوی) و!=(نامساوی). -
بدنهٔ حلقه تورفتگی دارد: تورفتگی روش پایتون برای گروهبندی دستورهاست. در اعلان تعاملی، برای هر خط تورفته باید یک tab یا فاصله(ها) تایپ کنید. در عمل ورودیهای پیچیدهتر را با یک ویرایشگر متن برای پایتون آماده میکنید؛ همهٔ ویرایشگرهای متنِ درستوحسابی قابلیت تورفتگی خودکار دارند. وقتی یک دستور مرکب بهصورت تعاملی وارد میشود، باید با یک خط خالی دنبال شود تا پایان آن مشخص شود (چون تجزیهگر نمیتواند حدس بزند کی آخرین خط را تایپ کردهاید). توجه کنید که هر خط درون یک بلوک پایه باید به یک اندازه تورفتگی داشته باشد.
-
تابع
print()مقدار آرگومان(های) دادهشده را مینویسد. این با نوشتن صرف عبارتی که میخواهید بنویسید (همانطور که پیشتر در مثالهای ماشینحساب کردیم) از نظر نحوهٔ مدیریت آرگومانهای متعدد، مقادیر ممیز شناور و رشتهها فرق دارد. رشتهها بدون گیومه چاپ میشوند و بین آیتمها یک فاصله درج میشود، تا بتوانید چیزها را به شکل زیبایی قالببندی کنید، مانند این:>>> i = 256*256 >>> print('The value of i is', i) The value of i is 65536از آرگومان کلیدواژهای end میتوان برای جلوگیری از خط جدید پس از خروجی، یا پایان دادن خروجی با رشتهای متفاوت استفاده کرد:
>>> a, b = 0, 1 >>> while a < 1000: ... print(a, end=',') ... a, b = b, a+b ... 0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
پاورقیها
[۱] از آنجا که ** تقدم بالاتری از - دارد، -3**2 بهصورت -(3**2) تفسیر میشود و در نتیجه -9 میدهد. برای جلوگیری از این و گرفتن 9، میتوانید از (-3)**2 استفاده کنید.
[۲] بر خلاف زبانهای دیگر، نویسههای ویژه مانند \n با هر دو نوع گیومهٔ تکی ('...') و جفت ("...") معنای یکسانی دارند. تنها تفاوت این دو آن است که درون گیومهٔ تکی لازم نیست " را escape کنید (اما باید \' را escape کنید) و برعکس.