مقدمه
در این فصل، به بررسی نوعهای دادهای (datatypes) که میتوان
در برنامههای پایتون از آنها استفاده کرد، خواهیم پرداخت
و با متغیرهای پایتون (python variables) و روشهای تعریف
و استفاده از آنها آشنا خواهیم شد. درس جاری که اولین درس
از این فصل محسوب میشود، به بررسی روش تعریف متغیرها و
کاربرد آنها در برنامههای پایتون اختصاص دارد.
تعریف متغیر در پایتون
تعریف متغیر در زبان پایتون بسیار ساده است و بر خلاف زبانهای
استاتیکی مانند C و جاوا، به اعلان نوع (type declaration)
نیاز ندارد. برای دیدن این مطلب، برنامهی hello_world فصل
قبل را به شکل زیر ویرایش میکنیم.
hello_world.py
message = "Hello Python world!"
print(message)
اگر برنامه را اجرا کنید، خواهید دید که همانند قبل،
عبارت Hello Python World! را در خروجی نمایش
میدهد. خط اول شامل تعریف یک متغیر با نام message و
اختصاص مقدار متنی مورد نظر به این متغیر است. در خط دوم
هم مقدار ذخیره شده در متغیر message با استفاده از تابع
print() چاپ میشود.
مقدار یک متغیر در طول برنامه میتواند تغییر کند. برای مثال،
در کد زیر پس از چاپ مقدار متغیر message، مقدار جدیدی را
به این متغیر نسبت داده و مجدداً آن را چاپ کردهایم.
hello_world.py
message = "Hello Python world!"
print(message)
message = "Hello Python!"
print(message)
حالا اگر برنامه را اجرا کنیم، خروجی زیر را مشاهده خواهیم کرد.
Hello Python world!
Hello Python!
علاوه بر مقدار یک متغیر پایتون، نوع آن نیز میتواند در طول
برنامه تغییر کند. یعنی متغیری مانند message در مثال بالا
که دارای مقداری متنی است، میتواند در ادامه، یک مقدار
عددی یا بولین یا مقداری از هر نوع دیگر را دریافت کند.
این امر از دینامیک بودن سیستم نوع (type system) در
پایتون ناشی میشود. به بیان دقیق، پایتون یک زبان با
سیستم نوع دینامیک (dynamically typed system) است.
آیا متغیرهای پایتون فاقد نوع هستند؟
بعضیها از اصطلاح فاقد نوع (untyped) برای متغیرهای
پایتون (و دیگر زبانهای دینامیک) استفاده میکنند
که تعبیر غلطی است. این که در زبانی
مانند C# تعریف متغیرها با اعلان نوع
همراه باشد (مانند int x = 10) و در زبانی مانند
پایتون نیاز به اعلان نوع نباشد (x=10)، به این
معنی نیست که متغیرهای C# دارای نوع
هستند و متغیرهای پایتون فاقد نوع. متغیرهای
پایتون و هر زبان دیگر دارای نوع هستند؛ منتها
تفاوت به استاتیک یا دینامیک بودن سیستم نوع
برمیگردد که تعیین میکند که نوع متغیرها در طول
برنامه قابل تغییر باشد یا خیر. پس، با وجودی که
ما نوع متغیرهای پایتون را صراحتاً اعلان
نمیکنیم، این متغیرها دارای نوع هستند و مفسر
پایتون، نوع یک متغیر را از روی آخرین مقداری که
دریافت کرده، استنتاج میکند.
نامگذاری و استفاده از متغیرها
هنگام کار با متغیرهای پایتون باید چند نکته را مد نظر داشته
باشید. برخی از این نکات جنبهی قانون دارند و رعایت آنها
الزامی است و برخی دیگر صرفاً توصیهها و قراردادهایی
هستند که البته هر چند اجباری نیستند اما بهتر است رعایت
شوند:
- نام متغیرها میتواند فقط شامل حروف، اعداد و کاراکتر
underscore باشد. در ضمن، نام متغیر نباید
با یک عدد شروع شود. برای مثال، message_1 یک نام
معتبر و 1_message یک نام غیر معتبر است.
- استفاده از space در نام متغیرها مجاز نیست. اگر
بخواهیم از بیش از یک کلمه برای تعیین نام یک
متغیر استفاده کنیم، بهتر است کلمات را با
underscore از هم جدا کنیم. برای مثال،
greeting_message یک نام معتبر است اما greeting
message خیر.
- استفاده از کلمات کلیدی پایتون و نام توابع برای
نامگذاری متغیرها مجاز نیست. برای مثال،
نمیتوانیم از نام print برای یک متغیر استفاده
کنیم، چون این کلمات برای مفسر پایتون معنای مشخصی
دارند و اصطلاحاً توسط مفسر رزرو شدهاند.
- بهتر است برای نام متغیرها از عباراتی استفاده کنیم که
حتیالامکان کوتاه باشند اما نقش متغیر را به خوبی
نشان دهند. برای مثال، name نسبت به n مناسبتر
است یا student_name نسبت به s_n نام بهتری است و
یا name_length نسبت به length_of_person_name نام
مناسبتری است.
هر چقدر که برنامههای بیشتری بنویسید و کدهای بیشتری ببینید،
مهارت انتخاب نام متغیرها در شما تقویت میشود.
خطاهای مربوط به نام متغیرها
هر برنامهنویسی اشتباه میکند و این امری اجتنابناپذیر است
اما موضوع مهم، به مواجهه با خطای رخداده و اصلاح برنامه
مربوط میشود. اجازه دهید یک خطای عمدی در برنامه تولید
کنیم و ببینیم چه اتفاقاتی رخ میدهد.
در کد زیر، نام متغیر message به اشتباه به صورت mesage به تابع
print() داده شده و طبیعتاً اجرای این کد با خطا همراه خواهد
بود.
message = "Hello Python!"
print(mesage)
وقتی خطاهایی از این دست در برنامه رخ میدهد، مفسر پایتون سعی
میکند به ما کمک کند که منبع خطا را پیدا کنیم. در واقع،
وقتی اجرای یک برنامه موفقیتآمیز نباشد، مفسر یک
traceback ارائه میدهد که جایی از برنامه را که باعث
تولید خطا شده، نشان میدهد. برای مثال، اشتباه تایپی
موجود در کد بالا منجر به ارائهی traceback زیر توسط مفسر
پایتون میشود.
Traceback (most recent call last):
1 File "hello_world.py", line 2, in <module>
2 print(mesage)
^^^^^^
3 NameError: name 'mesage' is not defined. Did you mean: 'message'?
چیزی که این خروجی گزارش میکند این است که یک خطا در خط 2 از
فایل hello_world.py رخ داده است (1). در ادامه، مفسر خطی
را که باعث بروز خطا شده نمایش میدهد (2) و سپس، نوع خطا
را اعلام میکند (3). در این مثال، خطایی که رخ داده، از
نوع name error است که باعث شده آرگومان تابع print() برای
مفسر قابل شناسایی نباشد. یک name error معمولاً یا زمانی
رخ میدهد که فراموش کردهایم قبل از استفاده از یک متغیر،
مقداری را به آن تخصیص دهیم و یا مانند مثال بالا یک
اشتباه املایی یا تایپی مرتکب شدهایم. همانطور که در
خروجی بالا هم میبینید، اگر مفسر پایتون متغیری را در
برنامه پیدا کند که نامش شبیه به متغیر غیر قابل شناسایی
باشد، به ما اعلام میکند که شاید منظورمان آن متغیر بوده
است.
این دست خطاهای کوچک و ساده برای همه رخ میدهد و برنامهنویسان
با تجربه و مستعد گاهی ساعتها به دنبال رفع همین اشکالات
ساده هستند. پس، فراوانی این دست خطاها نباید حس منفی در
شما ایجاد کند.
درک متغیر به عنوان برچسبی برای یک مقدار
معمولاً متغیرها را به عنوان باکسهایی توصیف میکنند که
میتوان مقداری را در آنها ذخیره کرد. این ایده برای شروع
مفید است و به ما کمک میکند که مفهوم متغیرها را درک کنیم
اما توصیف دقیقی از نحوهی نمایش داخلی متغیرهای پایتون
ارائه نمیدهد. بهتر است یک متغیر را به عنوان یک برچسب
(label) تلقی کنیم که روی یک مقدار زده می شود.
درک این تمایز در این مرحله چندان مهم نیست و مشکلی در
برنامههای شما ایجاد نمیکند اما نقطهای وجود دارد که
رفتار غیر قابل انتظاری را از یک متغیر میبینیم و در آن
نقطه درک دقیق نحوهی عملکرد متغیرها به ما کمک میکند که
بفهمیم چه اتفاقی در برنامه رخ داده است.
جداسازی ارقام با کاراکتر Underscore
برای اینکه خواندن اعدادی که ارقام بیشتری دارند، سادهتر باشد، میتوانیم از کاراکتر _ به
عنوان جدا کنندهی ارقام استفاده کنیم.
>>> universe_age = 14_000_000_000
>>> print(universe_age)
14000000000
همانطور که میبینید، عدد مورد نظر بدون کاراکترهای _ در خروجی چاپ شده است. پس، پایتون
کاراکترهای _ در بین ارقام یک عدد را نادیده میگیرد و ما میتوانیم از این موضوع برای
سادهتر شدن خواندن عدد استفاده کنیم.
ثابتها
یک ثابت (constant) متغیری است که مقدارش در طول حیات برنامه تغییر نمیکند. در پایتون
نوعهای ثابت built-in وجود ندارد اما برنامهنویسان پایتون برای تعریف متغیری که مقدارش
باید در طول برنامه ثابت بماند، نام آن متغیر را با حروف بزرگ مینویسند. مثال زیر را
ببینید.
>>> SPEED_OF_LIGHT = 299_792_458
تأکید میکنم که این یک قرارداد بین برنامهنویسان پایتون است و در عمل، اگر مقدار متغیر
بالا را تغییر دهیم، این تغییر بدون گزارش خطا رخ میدهد.