متغیرها در پایتون، اسامی نمادینی برای اشاره به اشیاء یا مقادیر ذخیره شده در حافظه کامپیوتر شما هستند. متغیرها به شما این امکان را میدهند که اسامی توصیفی مناسبی برای دادههای خود انتخاب کنید. به کمک متغیرها میتوانید راحتتر از دادهها استفاده مجدد کنید. متغیرها شما را قادر میسازند بتوانید یک مقدار یا یک داده مشخص را به کرات در کدهای خود استفاده کنید و یا تغییر دهید.
فهرست مطالب:
در این مجموعه نوشته پیرامون متغیرها در پایتون، ابتدا به معرفی مفهوم متغیر و شیوه استفاده از آن پرداخته میشود. سپس بهترین روشهای نامگذاری متغیر در کدهای پایتونی را خواهید آموخت و در نهایت، با مفاهیمی نظیر تایپ متغیر و اسکوپ آن آشنا خواهید شد.
ایجاد متغیرها در پایتون
اولین و سادهترین روش برای ایجاد متغیرها در پایتون، استفاده از عملگر تخصیص (assignment) یا همان علامت = است:
variable_name = value
در این سینتکس، اسم متغیر در سمت چپ نوشته میشود، سپس عملگر (=) نوشته میشود و نهایتاً مقداری که میخواهید به متغیر اختصاص دهید را وارد میکنید. مقدار متغیر در این ساختار، میتواند هر آبجِکت (شیء) پایتونی باشد؛ اعم از استرینگ، عدد، لیست، دیکشنری یا حتی آبجکتهایی که خودتان تعریف کردهاید.
در اینجا چند مثال از انواع دادههای قابل ذخیره در متغیرها آورده شده است:
>>> word = "Python"
>>> number = 42
>>> coefficient = 2.87
>>> fruits = ["apple", "mango", "grape"]
>>> ordinals = {1: "first", 2: "second", 3: "third"}
>>> class SomeCustomClass: pass
>>> instance = SomeCustomClass()
همانطور که مشاهده میکنید در ۵ مثال اول، متغیرها به انواع داده پیشساخته (built-in types) پایتون اشاره میکنند؛ اما در مثال آخر، یک کلاس دلخواه با نام SomeCustomClass تعریف شده و متغیر به آبجکتی از این کلاس دلخواه اشاره دارد.
تعریف و تغییر نوع متغیر
به جز مقدار متغیر، مهم است که به نوع داده آن نیز توجه کنید. متغیرها در پایتون به خودی خود تایپ ندارند بلکه آبجکتی که متغیر به آن اشاره دارد، تایپ دارد. پس وقتی شما در مورد نوع (type) متغیر صحبت میکنید در واقع میگویید این متغیر به یک استرینگ، یک عدد صحیح، یک عدد اعشاری، یک لیست، یک تاپل، یک دیکشنری یا یک آبجکت دلخواه اشاره دارد.
به عنوان مثال، متغیرهای زیر را در نظر بگیرید:
>>> name = "Jane Doe"
>>> age = 19
>>> subjects = ["Math", "English", "Physics", "Chemistry"]
>>> type(name)
<class 'str'>
>>> type(age)
<class 'int'>
>>> type(subjects)
<class 'list'>
در این مثال، مقدار "Jane Doe" به متغیر name اختصاص داده شده، بنابراین متغیر name یک استرینگ (str) است. یا متغیر age به عدد صحیح ۱۹ اشاره دارد، پس متغیر age یک عدد صحیح (int) است. دقت کنید که شما لازم نیست به پایتون بگویید مشخصاً این متغیر از چه نوع دادهای است! به محض این که شما مقدار را به متغیر اختصاص دهید، پایتون به صورت خودکار این کار را انجام میدهد.
در اصطلاح، پایتون یک زبان dynamically-typed است؛ به این معنی که نوع متغیرها در زمان اجرای کد (runtime) توسط مفسر زبان، تعریف و بررسی میشود. بر خلاف زبانهای statically-typed که نوع متغیر باید قبل از کامپایل کردن کد، تعریف شود. بنابراین شما میتوانید در هر زمانی، با اختصاص دادن مقدار جدید، نوع متغیر را تغییر دهید:
>>> age = "19"
>>> type(age)
<class 'str'>
>>> subjects = {"Math", "English", "Physics", "Chemistry"}
>>> type(subjects)
<class 'set'>
در این مثال میبینید که متغیر age دیگر یک عدد صحیح نیست و از نوع استرینگ شده است. همچنین متغیر subjects نیز دیگر یک لیست نیست و حالا نوع آن یک مجموعه (set) شده است.
کار با متغیرها در پایتون
متغیرها یکی از مفاهیم ضروری در برنامهنویسی پایتون هستند و به عنوان اجزای سازنده کدها و برنامههای شما رفتار میکنند. در بخشهای آینده با مثالهایی از برخی کاربردهای متغیرها در پایتون آشنا خواهید شد.
۱) استفاده در عبارتها
در پایتون، یک عبارت (Expression) به صورت گزارهای ساده تعریف میشود که میتواند ارزیابی شده و یک مقدار مشخص را برگرداند. به عنوان مثال، عبارتهای ساده زیر را در نظر بگیرید که محیط دایره را محاسبه میکنند:
>>> 2 * 3.1416 * 10
62.832
>>> 2 * 3.1416 * 20
125.664
هر کدام از این عبارتها، یک محاسبه خاص را نمایش میدهند و برای ساخت هر عبارت، از مقادیر و عملگر ضرب (*) استفاده شده است. مفسر پایتون، هر عبارت را ارزیابی کرده و مقدار نتیجه را بر میگرداند.
اما این شیوه نوشتن عبارتها به نوعی صُلب و بسته است. برای هر عبارت لازم است مقادیر ورودی تکرار شوند و احتمال خطای انسانی در انجام کارهای تکراری بالاست. اکنون، مثالهای زیر را در نظر بگیرید:
>>> pi = 3.1416
>>> radius = 10
>>> 2 * pi * radius
62.832
>>> radius = 20
>>> 2 * pi * radius
125.664
در اینجا، ابتدا متغیرهایی برای ذخیره کردن مقادیر ورودی تعریف شدهاند. سپس با استفاده از این متغیرها، عبارتها نوشته شدهاند. بزرگترین مزیت این روش در امکان استفاده چندباره از متغیرهاست. علاوه بر این، با استفاده از اسامی معناداری که برای متغیرهای خود انتخاب میکنید، به کاربران دیگر نیز امکان استفاده از کدهای خود را میدهید.
۲) شمارندهها
شمارندهها (Counters) یک متغیر عددی هستند که به شما امکان شماردن آبجکتها را میدهند. شمارندهها معمولاً از ۰ شروع میشوند و افزایش مقدار شمارنده، نمایشدهنده تعداد یک آبجکت خاص است. به عنوان مثال، فرض کنید که قرار است تعداد استرینگهای درون یک تاپل را بشمارید:
>>> str_counter = 0
>>> for item in ("Alice", 30, "Programmer", None, True, "Department C"):
... if isinstance(item, str):
... str_counter += 1
...
>>> str_counter
3
در این مثال، متغیر str_counter به عنوان شمارنده با مقدار ۰ تعریف میشود. سپس یک حلقه for روی تاپل اجرا میشود و در داخل حلقه، هر کدام از آیتمهای آن با استفاده از تابع isinstance بررسی میشود که آیا یک استرینگ است یا خیر. در صورتی که پاسخ تابع مثبت باشد، شمارنده ما یک واحد افزایش پیدا میکند.
۳) انباشتگرها
انباشتگرها (Accumulators)، یکی دیگر از کاربردهای متغیرها در برنامهنویسی هستند. یک انباشتگر، متغیری است که جمع کل مقادیر را درون خود نگهداری میکند. یک مثال ساده برای این مورد، وقتی است که نیاز دارید جمع چند عدد را محاسبه کنید:
>>> numbers = [1, 2, 3, 4]
>>> total = 0
>>> for number in numbers:
... total += number
...
>>> total
10
در این مثال، حلقه for روی آیتمهای لیست حرکت میکند و مقدار هر کدام را به متغیر total اضافه میکند.
انباشتگرها میتوانند یک جز میانی در محاسبات بزرگتر باشند. مثلاً محاسبه میانگین یک مجموعه از اعداد:
>>> total / len(numbers)
2.5
نکته: پایتون به صورت پیشفرض دارای مجموعهای از توابع پیشساخته است که این عملیات انباشت را برای شما انجام میدهند؛ مثلاً تابع sum برای مثال فوق میتواند راهحل سادهتر و اصولیتری باشد.
۴) متغیرهای موقت
متغیرهای موقت (Temporary Variables)، نتایج میانی مورد استفاده شما در ادامه کدها یا محاسبات را نگهداری میکنند. یک مثال کلاسیک برای این کاربرد زمانی است که شما میخواهید مقدار دو متغیر را با هم تعویض کنید:
>>> a = 5
>>> b = 10
>>> temp = a
>>> a = b
>>> b = temp
>>> a
10
>>> b
5
در این مثال، متغیر موقت temp مقدار a را درون خود نگه میدارد تا شما بتوانید مقدار b را به متغیر a اختصاص دهید. پس از این کار و مقداردهی به b، دیگر به متغیر temp نیازی ندارید.
نکته: در پایتون یک راه سادهتر (کد زیر) برای جابجایی مقدار دو متغیر وجود دارد و این مثال، صرفاً برای مقاصد آموزشی بود.
>>> a = 5
>>> b = 10
>>> a, b = b, a
>>> a
10
>>> b
5
مثال پیچیدهتر برای کاربرد متغیرهای موقت، تابع زیر است که برای محاسبه واریانس یک مجموعه از اعداد مورد استفاده قرار میگیرد:
>>> def variance(data, degrees_of_freedom=0):
... number_of_items = len(data)
... mean = sum(data) / number_of_items
... total_square_dev = sum((x - mean) ** 2 for x in data)
... return total_square_dev / (number_of_items - degrees_of_freedom)
...
>>> variance([3, 4, 7, 5, 6, 2, 9, 4, 1, 3])
5.24
همانطور که میبینید بخشی از متغیرهایی که درون تابع استفاده شدهاند، کاربرد مستقلی ندارند و صرفاً به منظور بهبود خوانایی کد، داخل تابع تعریف شدهاند.
۵) فلگها
پرچمها یا فِلگهای بولیَن (Boolean Flags) برای کنترل جریان کد و تصمیمگیری به شما کمک میکنند. همانطور که از اسم آنها مشخص است، این متغیرها میتوانند دو مقدار True یا False را داشته باشند و در ساختارهای شرطی، حلقههای while و عبارات منطقی میتوانید از آنها استفاده کنید.
>>> toggle = True
>>> for _ in range(4):
... if toggle:
... print(f"✓ toggle is {toggle}")
... print("Do something...")
... else:
... print(f"⨉ toggle is {toggle}")
... print("Do something else...")
... toggle = not toggle
...
✓ toggle is True
Do something...
⨉ toggle is False
Do something else...
✓ toggle is True
Do something...
⨉ toggle is False
Do something else...
در این مثال، در هر بار اجرای حلقه، ابتدا مقدار متغیر toggle بررسی میشود و بر اساس True یا False بودن آن، پایتون تصمیم میگیرد که چه کدهایی را اجرا کند. در پایان حلقه هم، هر بار مقدار آن عوض میشود.
یکی دیگر از کاربردهای فلگها، به عنوان آرگومان توابع است:
>>> def greet(name, verbose=False):
... if verbose:
... print(f"Hello, {name}! It's great to see you!")
... else:
... print(f"Hello, {name}!")
...
>>> greet("Pythonista")
Hello, Pythonista!
>>> greet("Pythonista", verbose=True)
Hello, Pythonista! It's great to see you!
در مثال بالا، آرگومان verbose یک فلگ بولین است که به تابع میگوید به چه صورت باید اجرا شود.
نکته مهم: در عمل، با هدف بهبود خوانایی کد برای انسان، معمولاً فلگها با پیشوندهای _is یا _has نامگذاری میشوند:
>>> age = 20
>>> is_adult = age > 18
>>> is_adult
True
در مثال فوق، متغیر is_adult یک فلگ بولین است که بر اساس مقدار متغیر age، تغییر میکند. استفاده از این پیشوندها باعث میشود که شما به سایر کسانی که کد شما را میخوانند کمک کنید تا کاربرد متغیرهایتان را بهتر متوجه شوند. البته این شیوه نامگذاری الزامی نیست اما بین برنامهنویسان به عنوان یک best practice متداول است.
۶) متغیرهای حلقه
متغیرهای حلقه (Loop Variables) با هدف پردازش داده حین اجرای حلقههای for و گاهی while ایجاد میشوند. به عنوان مثال در یک حلقه مانند کد زیر، متغیر color، مقدار فعلی آیتمی که در حلقه در حال استفاده است را درون خود نگه میدارد:
>>> colors = [
... "red",
... "orange",
... "yellow",
... "green",
... "blue",
... "indigo",
... "violet"
... ]
>>> for color in colors:
... print(color)
...
red
orange
yellow
green
blue
indigo
violet
۷) متغیرهای ذخیرهسازی داده
متغیرهای ذخیرهسازی داده (Data Storage Variables) به شما اجازه میدهند تا به عنوان یک ظرف یا کانتینر از آنها استفاده کنید و دادههای خود را درون آنها نگهداری کنید. لیستها، تاپلها، دیکشنریها و مجموعهها معمولاً برای این کاربری مورد استفاده قرار میگیرند.
به عنوان مثال، فرض کنید که شما یک برنامه فهرست مخاطبین ساختهاید. میتوانید از یک لیست برای ذخیرهسازی اطلاعات مخاطبین استفاده کنید:
>>> contacts = [
... ("Linda", "111-2222-3333", "linda@example.com"),
... ("Joe", "111-2222-3333", "joe@example.com"),
... ("Lara", "111-2222-3333", "lara@example.com"),
... ("David", "111-2222-3333", "david@example.com"),
... ("Jane", "111-2222-3333", "jane@example.com"),
... ]
این متغیر contacts به شما امکان میدهد تا بتوانید دادههای خود را ذخیره کرده و به شکل دلخواه نمایش دهید:
>>> for contact in contacts:
... print(contact)
...
('Linda', '111-2222-3333', 'linda@example.com')
('Joe', '111-2222-3333', 'joe@example.com')
('Lara', '111-2222-3333', 'lara@example.com')
('David', '111-2222-3333', 'david@example.com')
('Jane', '111-2222-3333', 'jane@example.com')
>>> for name, phone, email in contacts:
... print(phone, name)
...
111-2222-3333 Linda
111-2222-3333 Joe
111-2222-3333 Lara
111-2222-3333 David
111-2222-3333 Jane
در قسمت بعدی این مجموعه نوشته، با الزامات و روشهای متداول نامگذاری متغیرها در پایتون آشنا خواهیم شد.