Kahibaro
Discord Login Register

خطاهای رایج مبتدیان

Table of Contents

دسته‌بندی خطاهای رایج مبتدیان

در این بخش روی الگوهای اشتباهی تمرکز می‌کنیم که تقریباً همهٔ برنامه‌نویس‌های مبتدی با آن‌ها روبه‌رو می‌شوند. هدف این است که آن‌ها را بشناسید، سریع‌تر تشخیص‌شان دهید و بدانید چطور از تکرارشان جلوگیری کنید.

در مثال‌ها فرض می‌کنیم قبلاً می‌دانید خطا چیست و پیام خطا را چطور به‌طور کلی می‌خوانیم؛ اینجا سراغ مصداق‌های پر‌تکرار می‌رویم.

۱. جا انداختن دو‌نقطه (:) و مشکل تورفتگی (Indentation)

۱.۱. فراموش کردن `:` بعد از ساختارهای کنترلی

در if, elif, else, for, while, def, class باید در انتهای خط، : بگذارید.

مثال اشتباه:

if x > 10
    print("بزرگ‌تر از ۱۰ است")

پیام معمول: SyntaxError: expected ':'

نسخهٔ درست:

if x > 10:
    print("بزرگ‌تر از ۱۰ است")

همین اشتباه برای for, while, def, class هم تکرار می‌شود.

۱.۲. تورفتگی‌های نامنظم

پایتون روی فاصلهٔ ابتدای خط (indentation) بسیار حساس است. قاطی‌کردن فاصله‌ها (space) و تب (tab) یا تورفتگی نامساوی باعث خطا می‌شود.

مثال اشتباه:

if x > 10:
  print("خط ۱")
    print("خط ۲")

پیام معمول: IndentationError: unexpected indent یا IndentationError: unindent does not match any outer indentation level

نکات پیشگیری:

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

۲.۱. استفاده از نام اشتباه متغیر یا تابع

پایتون به حروف کوچک و بزرگ حساس است (case-sensitive). NameError وقتی رخ می‌دهد که پایتون متغیر/تابع را نمی‌شناسد.

مثال اشتباه:

age = 20
print(Age)

پیام: NameError: name 'Age' is not defined

نسخهٔ درست:

age = 20
print(age)

یا:

userName = "Ali"
print(username)   # اشتباه در املای نام

۲.۲. تعریف‌نکردن متغیر قبل از استفاده

گاهی اسم را درست نوشته‌اید، اما اصلاً قبلش تعریفش نکرده‌اید.

print(total)
total = 100

پیام: NameError: name 'total' is not defined

ترتیب درست:

total = 100
print(total)

۳. قاطی‌کردن `=` با `==`

مثال اشتباه (در شرط):

x = 5
if x = 5:
    print("x پنج است")

پیام: SyntaxError: invalid syntax

نسخهٔ درست:

x = 5
if x == 5:
    print("x پنج است")

برعکسش هم اتفاق می‌افتد: بعضی‌ها می‌خواهند مقدار بدهند ولی از == استفاده می‌کنند و برنامه رفتار مورد انتظار را ندارد.

x == 10  # فقط مقایسه است، مقداردهی نمی‌کند

۴. نوع دادهٔ نامناسب در عملگرها

این دستهٔ خطا معمولاً TypeError می‌دهد.

۴.1. جمع‌کردن عدد و رشته

age = 20
text = "سن شما: " + age

پیام: TypeError: can only concatenate str (not "int") to str

نسخهٔ درست (تبدیل به رشته):

age = 20
text = "سن شما: " + str(age)
print(text)

یا با قالب‌بندی (که در فصل ورودی/خروجی بیشتر دیده‌اید):

age = 20
print(f"سن شما: {age}")

۴.۲. تبدیل ورودی کاربر بدون توجه به نوع

تابع input() همیشه رشته برمی‌گرداند. اگر آن را مستقیم با عدد جمع کنید:

x = input("عدد را وارد کنید: ")
result = x + 10

پیام: TypeError: can only concatenate str (not "int") to str

برای حل، ورودی را به عدد تبدیل کنید (اگر انتظار عدد دارید):

x = int(input("عدد را وارد کنید: "))
result = x + 10
print(result)

۵. اشتباه در استفاده از پرانتز، کروشه و آکولاد

۵.۱. پرانتز بسته‌نشده یا زیادبستن

مثال اشتباه:

print("سلام"

پیام: SyntaxError: '(' was never closed یا مشابه.

مثال اشتباه دیگر:

print(("سلام"))
)

پیام: SyntaxError: unmatched ')'

برای جلوگیری:

۵.۲. قاطی‌کردن `()` و `[]` و `{}`

هرکدام کاربرد خودشان را دارند:

مثال اشتباه:

numbers = [1, 2, 3]
print(numbers(0))   # اشتباه

پیام: TypeError: 'list' object is not callable

درست:

numbers = [1, 2, 3]
print(numbers[0])

یا:

person = {"name": "Ali"}
print(person("name"))   # اشتباه

باید بنویسید:

print(person["name"])

۶. استفادهٔ اشتباه از اندیس‌ها در لیست و رشته

۶.۱. خارج از محدوده (IndexError)

مثال:

numbers = [10, 20, 30]
print(numbers[3])

اندیس‌های معتبر: 0, 1, 2؛ اندیس 3 وجود ندارد.

پیام: IndexError: list index out of range

نسخهٔ درست:

numbers = [10, 20, 30]
print(numbers[2])   # آخرین عنصر

یا قبل از دسترسی، طول را چک کنید:

index = 3
if index < len(numbers):
    print(numbers[index])
else:
    print("چنین اندیسی وجود ندارد")

۶.۲. فرض‌گرفتن این‌که رشته/لیست خالی نیست

مثال:

text = ""
print(text[0])

پیام: IndexError: string index out of range

راه حل: قبل از دسترسی، چک کنید خالی نباشد:

if text:
    print(text[0])
else:
    print("رشته خالی است")

۷. اشتباه در حلقه‌ها: حلقهٔ بی‌نهایت و شمارندهٔ اشتباه

۷.۱. حلقهٔ بی‌نهایت ناخواسته

مثال:

x = 0
while x < 5:
    print(x)
    # فراموش کرده‌ایم x را تغییر دهیم

این حلقه هرگز تمام نمی‌شود.

درست:

x = 0
while x < 5:
    print(x)
    x = x + 1

۷.۲. تغییر دادن لیست هنگام پیمایش با `for`

مثال اشتباه:

numbers = [1, 2, 3, 4]
for n in numbers:
    if n % 2 == 0:
        numbers.remove(n)
print(numbers)

نتیجه معمولاً چیزی است که انتظار ندارید. این خطانمای منطقی است، نه لزوماً خطای اجرایی.

برای حذف امن، یا روی یک کپی حلقه بزنید:

numbers = [1, 2, 3, 4]
for n in numbers[:]:
    if n % 2 == 0:
        numbers.remove(n)

یا از روش‌های دیگر (مثل ساختن لیست جدید) استفاده کنید.

۸. اشتباه در شرط‌ها و عملگرهای منطقی

۸.۱. شرط همیشه درست یا همیشه غلط

مثال:

age = 20
if age > 18 or age < 10:
    print("شرط برقرار است")

در نگاه اول شاید معنی‌دار به‌نظر برسد، اما برای خیلی از مقادیر، شرط تقریباً همیشه درست است. اغلب از and باید استفاده شود.

اگر می‌خواستید بگویید «بزرگ‌تر از ۱۸ و کوچک‌تر از ۱۰ نیست»، باید منطق را دقیق بررسی کنید.

۸.۲. استفاده از `=` به‌جای `==` در شرط (که قبلاً گفتیم)

این هم هم‌زمان خط سینتکسی و منطقی است؛ هم اجرا نمی‌شود، هم به معنی موردنظر نیست.

۹. تکرار نام توابع و متغیرها روی نام‌های داخلی

۹.۱. بازنویسی توابع داخلی پایتون

مثال:

print = "سلام"
print("چاپ کن")

پیام: TypeError: 'str' object is not callable

چون حالا print دیگر تابع نیست، یک رشته است.

مشابه این اشتباه با list, str, sum, max و... هم رخ می‌دهد:

list = [1, 2, 3]
new_list = list("abc")  # اینجا دیگر تابع list را نداریم

راه‌حل:

del print

(اما در اسکریپت بهتر است از اول نام مناسبی انتخاب کنید.)

۱۰. فراموش‌کردن پرانتز در فراخوانی تابع

وقتی تابع را می‌خواهید اجرا کنید، باید () را اضافه کنید؛ در غیر این صورت فقط به خود شیٔ تابع اشاره می‌کنید.

مثال:

def say_hello():
    print("سلام")
say_hello       # هیچ‌چیزی چاپ نمی‌شود

درست:

say_hello()

این اشتباه در input, print و توابع کتابخانه‌ها هم زیاد رخ می‌دهد.

۱۱. اشتباه در استفاده از `return` در توابع

۱۱.۱. چاپ به جای بازگرداندن مقدار

مثال:

def add(a, b):
    print(a + b)
result = add(2, 3)
print(result)

خروجی:

اگر می‌خواهید مقدار در متغیر ذخیره شود، باید return کنید:

def add(a, b):
    return a + b
result = add(2, 3)
print(result)

۱۱.۲. فراموش‌کردن `return` در بعضی مسیرهای تابع

مثال:

def check_positive(x):
    if x > 0:
        return "مثبت است"
    # در غیر این صورت چیزی برنمی‌گرداند
print(check_positive(-5))  # None

بهتر است در همهٔ مسیرها مقدار برگردانده شود:

def check_positive(x):
    if x > 0:
        return "مثبت است"
    else:
        return "مثبت نیست"

۱۲. اشتباه در کار با فایل‌ها

۱۲.۱. فراموش‌کردن بستن فایل

گرچه در عمل خیلی وقت‌ها برنامه کوچک است و مشکلی ایجاد نمی‌کند، اما عادت بدی است.

مثال (روش ضعیف):

f = open("data.txt", "r")
content = f.read()
# فراموش کرده‌ایم f.close() را صدا بزنیم

روش استاندارد (با with — توضیح کاملش در فصل فایل‌ها):

with open("data.txt", "r") as f:
    content = f.read()

۱۲.۲. بازکردن فایل در حالت اشتباه

مثال:

f = open("data.txt", "r")
f.write("سلام")

پیام: io.UnsupportedOperation: not writable

برای نوشتن باید حالت را w یا a بگذارید:

with open("data.txt", "w") as f:
    f.write("سلام")

۱۳. بدفهمی پیام خطا و نادیده‌گرفتن خط آخر

یک خطای تکراری مبتدیان این است که:

نکته‌های عملی:

  1. همیشه خط آخر پیام خطا را بخوانید؛ آنجا نوع خطا و جملهٔ توضیحی کوتاه نوشته شده.
  2. خط قبل از آن معمولاً شمارهٔ خط و نام فایل را نشان می‌دهد؛ همان‌جا را بررسی کنید.
  3. اگر از اینترنت کمک می‌گیرید، متن کامل خطا را (بدون اطلاعات شخصی) جست‌وجو کنید.

مثال پیام خطا:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    print(x)
NameError: name 'x' is not defined

برای تمرین، سعی کنید:

۱۴. راهبردهای ساده برای جلوگیری از خطاهای رایج

در کنار فصل «راهبردهای اشکال‌زدایی»، چند توصیه مخصوصِ همین خطاهای مبتدیانه:

  1. کد را تکه‌تکه بنویسید و اجرا کنید
    به‌جای نوشتن ۵۰ خط و بعد اجرا، هر ۳–۵ خط یک بار برنامه را اجرا کنید.
  2. از چاپ (print) برای فهمیدن وضعیت استفاده کنید
    وقتی نتیجه عجیب است، در بخش‌های مهم مقدار متغیرها را چاپ کنید.
  3. به پیام‌های خطا احترام بگذارید
    قبل از هر کاری، آرام پیام را بخوانید و کلمه‌های کلیدی‌اش را ترجمه یا جست‌وجو کنید.
  4. نام متغیرها و توابع را معنی‌دار انتخاب کنید
    این کار هم جلوی NameError می‌گیرد، هم خوانایی را بالا می‌برد.
  5. از ویرایشگر مناسب استفاده کنید
    ویرایشگری که:
    • تورفتگی را نشان دهد،
    • پرانتزها را جفت کند،
    • کلمات کلیدی را رنگی کند،
      کمک زیادی برای جلوگیری از خطاهای نحوی می‌کند.

با شناختن این الگوهای تکراری، به‌مرور قبل از این‌که خطا رخ دهد، آن را در ذهن‌تان تشخیص می‌دهید و کد شما تمیزتر و پایدارتر می‌شود.

Views: 5

Comments

Please login to add a comment.

Don't have an account? Register now!