رفتن به محتوا
پایتون از صفراصول زباندرس ۲ از ۱۰

متغیر و نوع داده

متغیر یعنی اسمی برای یک مقدار؛ چهار نوع پایه‌ی str و int و float و bool، دیدن نوع با type، تبدیل با int و str و float، کار با متن (چسباندن، f-string، upper، split، replace، اندیس و برش)، مقایسه و and/or/not، و خطاهای TypeError و ValueError.

  • حدود ۱۸ دقیقه مطالعه
  • ۸ مثال اجراشده
  • ۳ تمرین با جواب
  • مقدماتی تا متوسط
  • به‌روزرسانی: ۲۹ مهر ۱۴۰۵

توی این درس یاد می‌گیری مقدارها را در متغیر نگه داری و با آن‌ها کار کنی. چهار نوع داده‌ی پایه‌ی پایتون را می‌شناسی: متن (str)، عدد صحیح (int)، عدد اعشاری (float) و درست/غلط (bool). می‌بینی چرا "5" + 3 خطا می‌دهد و چطور با int() و str() نوع را عوض کنی، و یاد می‌گیری متن را بچسبانی، با f-string قالب‌بندی کنی، بشکنی و تکه‌اش را برداری. در آخر با مقایسه (==، <) و ترکیب شرط‌ها (and، or، not) آماده‌ی درس شرط می‌شوی.

مسئله: کامپیوتر باید چیزها را «به خاطر بسپارد»

Section titled “مسئله: کامپیوتر باید چیزها را «به خاطر بسپارد»”

در درس قبل input اسم کاربر را گرفت و در name گذاشت. بدون آن، جواب کاربر همان لحظه گم می‌شد. هر برنامه‌ی واقعی پر از مقدارهایی است که باید نگه داشته شوند و تغییر کنند: موجودی حساب، تعداد خطاها، اسم فایل بعدی. و کامپیوتر باید بداند هر مقدار چه نوعی است: «۵» را باید جمع بزند یا مثل یک کلمه کنار بقیه بگذارد؟

متغیر مثل یک برچسب است که روی یک جعبه می‌چسبانی. جعبه (مقدار) چیزی را نگه می‌دارد و برچسب (اسم) راه پیدا کردنش است. age = 30 یعنی «جعبه‌ای با عدد ۳۰ بساز و برچسب age را رویش بزن». بعداً می‌توانی برچسب را بکنی و روی جعبه‌ی دیگری بزنی (age = 31). نوع هم مثل جنس جعبه است: جعبه‌ی شیشه‌ای مایع نگه می‌دارد و جعبه‌ی مقوایی کاغذ؛ نمی‌شود هر کاری را با هر جعبه‌ای کرد.

همه‌ی فایل‌ها را در ~/py بساز (cd ~/py). یک خط‌ها را هم می‌توانی در حالت تعاملی (python3) امتحان کنی.

مثال ۱: اولین متغیرها و type

Section titled “مثال ۱: اولین متغیرها و type”
vars.py
name = "علی"
age = 30
height = 1.78
is_student = False
print(name, age, height, is_student)
print(type(name), type(age), type(height), type(is_student))
age = age + 1
print("سال بعد:", age)
خروجی
علی 30 1.78 False
<class 'str'> <class 'int'> <class 'float'> <class 'bool'>
سال بعد: 31
  • = یعنی «مقدار سمت راست را در اسم سمت چپ بگذار». این برابری ریاضی نیست: age = age + 1 یعنی «مقدار فعلی age به‌اضافه‌ی یک را حساب کن و دوباره در age بگذار».
  • type(x) نوع مقدار را می‌گوید.
نوع اسم کامل نمونه برای
str string (رشته) "علی"، 'hello'، "123" متن (هر چیزی داخل کوتیشن)
int integer (عدد صحیح) 30، -5، 0 شمردن، شماره
float عدد اعشاری 1.78، 3.0، -0.5 اندازه، قیمت اعشاری
bool boolean (منطقی) True، False بله/خیر، روشن/خاموش

دقت کن True و False با حرف اول بزرگ و بدون کوتیشن‌اند، و "123" (با کوتیشن) متن است، نه عدد.

قاعده‌ی اسم‌گذاری: حرف انگلیسی، عدد و _؛ با عدد شروع نشود؛ فاصله نداشته باشد. رسم پایتون: حروف کوچک و _ بین کلمه‌ها (user_name، total_price). اسم‌ها حساس به حروف بزرگ و کوچک‌اند: Age و age دو متغیر جدا هستند.

مثال ۲: متن و عدد با هم جمع نمی‌شوند

Section titled “مثال ۲: متن و عدد با هم جمع نمی‌شوند”
mix.py
x = "5"
print(x + 3)
خروجی
Traceback (most recent call last):
File "/home/ali/py/mix.py", line 2, in <module>
print(x + 3)
~~^~~
TypeError: can only concatenate str (not "int") to str

TypeError یعنی «این کار با این نوع ممکن نیست». + روی دو متن یعنی چسباندن و روی دو عدد یعنی جمع؛ روی یک متن و یک عدد، پایتون حدس نمی‌زند منظورت کدام است و خطا می‌دهد. (این سخت‌گیری خوب است: جلوی باگ «۲۹۱» را می‌گیرد.)

برای اینکه خودت بگویی منظورت چیست، نوع را تبدیل کن:

convert.py
x = "5"
y = 3
print(int(x) + y)
print(x + str(y))
print(float("2.5") * 2)
print(int(3.99))
print(round(3.567, 2))
print(bool(0), bool(1), bool(""), bool("سلام"))
خروجی
8
53
5.0
3
3.57
False True False True
تابع کار نکته
int(x) به عدد صحیح int(3.99) اعشار را دور می‌ریزد (۳)، گرد نمی‌کند
float(x) به عدد اعشاری float("2.5")
str(x) به متن برای چسباندن عدد به متن
round(x, n) گرد کردن تا n رقم اعشار round(3.567, 2) می‌شود 3.57
bool(x) به درست/غلط 0، "" (متن خالی) و None غلط‌اند؛ بقیه درست
⚡ بررسی سریع

خروجی print("2" + "2") چیست؟

مثال ۴: input همیشه متن برمی‌گرداند

Section titled “مثال ۴: input همیشه متن برمی‌گرداند”
age.py
age = input("سنت چند است؟ ")
print(type(age))
print("سال بعد:", int(age) + 1)
صفحه (جواب: 29)
سنت چند است؟ 29
<class 'str'>
سال بعد: 30

حتی وقتی کاربر عدد تایپ می‌کند، input آن را متن (str) برمی‌گرداند؛ برای همین int(age) لازم است. یک نکته‌ی جالب: int() پایتون عدد فارسی را هم می‌فهمد؛ اگر کاربر ۲۹ بنویسد هم جواب 30 می‌شود (برخلاف ترمینال که عدد فارسی را نمی‌شناخت). ولی اگر چیزی بنویسد که اصلاً عدد نیست:

صفحه (جواب: بیست)
سنت چند است؟ بیست
<class 'str'>
Traceback (most recent call last):
File "/home/ali/py/age.py", line 3, in <module>
print("سال بعد:", int(age) + 1)
^^^^^^^^
ValueError: invalid literal for int() with base 10: 'بیست'

ValueError یعنی «نوع درست است (متن)، ولی مقدارش را نمی‌توانم تبدیل کنم». در درس «خطا و ماژول» یاد می‌گیری این خطا را بگیری و از کاربر دوباره بپرسی.

متن‌ها ابزارهای زیادی دارند. اسم را انگلیسی گرفته‌ایم تا بزرگ و کوچک کردن حروف دیده شود:

text.py
first = "Ali"
last = "Rezaei"
full = first + " " + last
print(full)
print(full.upper(), full.lower())
print(len(full))
print(full[0], full[-1], full[0:3])
print(" trim me ".strip() + "|")
print("a,b,c".split(","))
print("Rezaei".replace("e", "E"))
print("Ali" in full, "Sara" in full)
خروجی
Ali Rezaei
ALI REZAEI ali rezaei
10
A i Ali
trim me|
['a', 'b', 'c']
REzaEi
True False
کد کار
a + b چسباندن دو متن (فاصله را خودت بگذار)
s.upper() / s.lower() همه‌ی حروف بزرگ / کوچک
len(s) تعداد حرف‌ها (فاصله هم یک حرف است)
s[0] / s[-1] حرف اول / آخر (شماره‌ها از صفر شروع می‌شوند)
s[0:3] برش: از شماره‌ی ۰ تا قبل از ۳
s.strip() حذف فاصله‌های اول و آخر
s.split(",") شکستن به یک لیست (درس لیست‌ها)
s.replace(a, b) جایگزینی همه‌ی aها با b
"x" in s آیا x داخل s هست؟ (True/False)

نقطه‌ی بعد از اسم متغیر (full.upper()) یعنی «کاری که مخصوص این نوع است». این‌ها متد (method) نام دارند. نکته‌ی مهم: متدها متن اصلی را عوض نمی‌کنند؛ یک متن جدید برمی‌گردانند. اگر می‌خواهی نگهش داری: full = full.upper().

مثال ۶: f-string، تمیزترین راه ساختن متن

Section titled “مثال ۶: f-string، تمیزترین راه ساختن متن”

چسباندن با + و str() زود شلوغ می‌شود. f-string (یک f قبل از کوتیشن) اجازه می‌دهد متغیرها را مستقیم داخل { } بگذاری:

fstr.py
first = "Ali"
print(f"اسم: {first}، طول اسم: {len(first)}")
price = 125000
print(f"قیمت: {price:,} تومان")
print(f"{10/3:.2f}")
خروجی
اسم: Ali، طول اسم: 3
قیمت: 125,000 تومان
3.33

داخل { } هر عبارت پایتونی می‌آید. بعد از : می‌شود قالب داد: :, جداکننده‌ی هزارگان و :.2f دو رقم اعشار. از این به بعد در دوره تقریباً همیشه از f-string استفاده می‌کنیم.

مقایسه همیشه True یا False برمی‌گرداند:

logic.py
print(5 == 5, 5 != 3, 3 < 2, "a" < "b")
print(True and False, True or False, not True)
age = 20
print(age >= 18 and age < 65)
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(round(0.1 + 0.2, 2) == 0.3)
خروجی
True True False True
False True False
True
0.30000000000000004
False
True
  • == (دو مساوی) یعنی «برابر است؟» و = (یک مساوی) یعنی «بگذار». قاطی کردنشان اشتباه شماره‌ی یک است.
  • != نابرابر؛ <، >، <=، >= مثل ریاضی. متن‌ها به ترتیب الفبا مقایسه می‌شوند.
  • and: هر دو درست؛ or: دست‌کم یکی درست؛ not: برعکس.
  • عددهای اعشاری دقیق نیستند: 0.1 + 0.2 دقیقاً 0.3 نمی‌شود (پشت پرده). برای مقایسه‌شان اول گرد کن، و برای پول از عدد صحیح (مثلاً ریال) استفاده کن.

مثال ۸: میان‌برهای تغییر مقدار

Section titled “مثال ۸: میان‌برهای تغییر مقدار”
x = 10
x += 5
print(x)
x *= 2
print(x)
print(7 % 2, 8 % 2)
خروجی
15
30
1 0

x += 5 همان x = x + 5 است (و -=، *=، /= هم هست). % (باقی‌مانده) برای فهمیدن زوج و فرد عالی است: باقی‌مانده‌ی تقسیم بر ۲، برای عدد زوج صفر است.

پشت پرده: متغیر در حافظه

Section titled “پشت پرده: متغیر در حافظه”

وقتی می‌نویسی age = 30، پایتون یک شیء (object) عدد ۳۰ در حافظه می‌سازد و اسم age را به آن وصل می‌کند. اسم خودش مقدار را در خود ندارد؛ فقط به آن اشاره می‌کند. برای همین در پایتون نوع مال مقدار است، نه مال اسم: x = 5 و بعد x = "پنج" کاملاً مجاز است (به این می‌گویند نوع‌دهی پویا). این انعطاف راحت است، ولی یعنی تو باید حواست باشد هر لحظه در یک متغیر چه نوعی هست؛ type() همیشه دم دستت است.

اسم به مقدار اشاره می‌کند؛ با = جدید، اسم به مقدار دیگری وصل می‌شود و مقدار قبلی اگر کسی به آن اشاره نکند پاک می‌شود.

و چرا 0.1 + 0.2 دقیق نیست؟ کامپیوتر عددها را در مبنای ۲ نگه می‌دارد (درس «بیت و بایت» در دوره‌ی مبانی). همان‌طور که 1/3 در مبنای ده یک اعشار بی‌پایان است (0.333...)، 0.1 در مبنای دو هم بی‌پایان است و باید جایی بریده شود. این مشکل پایتون نیست؛ تقریباً همه‌ی زبان‌ها همین رفتار را دارند.

عملگر روی عدد روی متن
+ جمع چسباندن
* ضرب تکرار ("ha" * 3)
== != برابر / نابرابر برابر / نابرابر
< > کوچک‌تر / بزرگ‌تر ترتیب الفبا
in (نه) زیرمتن هست؟
خطا معنی
TypeError این کار با این نوع ممکن نیست (مثلاً متن + عدد)
ValueError نوع درست است ولی مقدار قابل‌تبدیل نیست (int("بیست"))
NameError متغیر تعریف نشده (یا قبل از تعریف استفاده شده)

۱) جمع کردن جواب input بدون تبدیل

Section titled “۱) جمع کردن جواب input بدون تبدیل”

input("عدد: ") + 1 خطای TypeError می‌دهد. راه‌حل: int(input("عدد: ")) + 1.

if age = 18: (درس بعد) SyntaxError می‌دهد. راه‌حل: مقایسه همیشه ==.

name = "Ali"
print("سلام {name}")
خروجی
سلام {name}

بدون f، {name} همان متن عادی است. راه‌حل: print(f"سلام {name}").

۴) فکر کردن اینکه متد متن را عوض می‌کند

Section titled “۴) فکر کردن اینکه متد متن را عوض می‌کند”
s = "ali"
s.upper()
print(s)
خروجی
ali

s.upper() یک متن جدید ساخت که جایی نگه داشته نشد. راه‌حل: s = s.upper().

"Ali"[1] حرف l است، نه A. راه‌حل: یادت باشد اولین حرف شماره‌ی صفر است؛ و s[-1] همیشه حرف آخر.

تمرینآسان

برنامه‌ای بنویس که قیمت یک کالا (عدد صحیح، به تومان) و تعدادش را در دو متغیر بگذارد و با f-string چاپ کند «جمع: ۳۷۵,۰۰۰ تومان» (با جداکننده‌ی هزارگان).

دیدن جواب
price.py
price = 125000
count = 3
total = price * count
print(f"جمع: {total:,} تومان")
خروجی
جمع: 375,000 تومان
تمرینمتوسط

تمرین اصلی: یک «ماشین‌حساب BMI» بنویس. وزن (کیلوگرم) و قد (متر، مثلاً 1.75) را با input بگیر، BMI را با فرمول وزن ÷ (قد × قد) حساب کن و با یک رقم اعشار چاپ کن. یادت باشد جواب input متن است.

دیدن جواب
bmi.py
weight = float(input("وزن (کیلوگرم): "))
height = float(input("قد (متر): "))
bmi = weight / (height * height)
print(f"BMI تو: {bmi:.1f}")
صفحه (جواب‌ها: 70 و 1.75)
وزن (کیلوگرم): 70
قد (متر): 1.75
BMI تو: 22.9

float لازم است چون قد اعشاری است. height ** 2 هم به‌جای height * height درست است.

تمرینسخت

یک ایمیل مثل Ali.Rezaei@Example.COM (با فاصله‌های اول و آخر) را تمیز کن: فاصله‌ها را بردار و همه را کوچک کن. بعد اسم کاربری (قبل از @) و دامنه (بعد از @) را جدا چاپ کن و بگو آیا دامنه با .com تمام می‌شود یا نه. (راهنما: split("@") یک لیست دوتایی می‌دهد؛ [0] و [1] اعضایش‌اند؛ متد endswith هم هست.)

دیدن جواب
email.py
raw = " Ali.Rezaei@Example.COM "
email = raw.strip().lower()
parts = email.split("@")
user = parts[0]
domain = parts[1]
print(f"ایمیل تمیز: {email}")
print(f"کاربر: {user}")
print(f"دامنه: {domain}")
print("دامنه‌ی .com است؟", domain.endswith(".com"))
خروجی
ایمیل تمیز: ali.rezaei@example.com
کاربر: ali.rezaei
دامنه: example.com
دامنه‌ی .com است؟ True

متدها را می‌شود پشت هم زد (raw.strip().lower()): خروجی اولی، ورودی دومی است.

آزمونک
  1. type("123") چه نوعی است؟

  2. خروجی int(7.9) چیست؟

  3. چرا "5" + 3 خطا می‌دهد؟

  4. خروجی "Python"[0:2] چیست؟

  5. فرق = و == چیست؟

  6. f"{3.14159:.2f}" چه می‌دهد؟

  • متغیر اسمی برای یک مقدار است: x = 5. = یعنی «بگذار»، نه برابری.
  • چهار نوع پایه: str (متن)، int (عدد صحیح)، float (اعشاری)، bool (True/False)؛ با type() ببین.
  • input همیشه متن است؛ با int() و float() تبدیل کن، با str() برعکس.
  • متن: + چسباندن، len، [i] و [a:b] (از صفر)، upper، strip، split، replace، in؛ و f-string برای ساختن متن.
  • مقایسه با ==، !=، <…؛ ترکیب با and، or، not. اعشاری‌ها دقیق نیستند.
  • TypeError = نوع نامناسب؛ ValueError = مقدار نامناسب.
برگه‌ی تقلب این درس
دستورکاری که می‌کند
x = 5ساختن/عوض کردن متغیر
type(x)نوع مقدار
int(s) / float(s) / str(n)تبدیل نوع
f"سلام {name}"متن با متغیر
f"{n:,}" / f"{x:.2f}"جداکننده‌ی هزارگان / دو رقم اعشار
s.strip().lower()تمیز کردن متن
s.split(",")شکستن متن به لیست
s[0] / s[-1] / s[0:3]حرف اول / آخر / برش
a == b / a != bبرابر / نابرابر
x += 1یکی اضافه کن