مبانی زبان

نحو، معنا و انواع خطا در پایتون

۴ دقیقه مطالعه · به‌روزرسانی ۲۲ مهر ۱۴۰۵

برنامه‌نویسی یعنی نوشتن دستورالعمل (recipe) برای کامپیوتر؛ دقیقاً مثل یک دستور پخت که قدم به قدم می‌گوید چه کنیم. هر زبان برنامه‌نویسی:

  • مجموعه‌ای از عملیات اولیه (primitive) در اختیارمان می‌گذارد، مثل جمع، مقایسه و چاپ.
  • اجازه می‌دهد این‌ها را در قالب عبارت (expression) ترکیب کنیم.
  • و هر عبارت یک مقدار و یک معنا دارد.

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

۱. نحو (Syntax)

نحو یعنی دستور زبان: کلمات به چه ترتیبی کنار هم بیایند تا جمله «درست ساخته شده» باشد.

از نظر نحوی نادرست از نظر نحوی درست
فارسی «او مهربان من» «او مهربان بود»
پایتون "hi"5 3.2 * 5

"hi"5 یعنی یک رشته و یک عدد بدون هیچ عملگری کنار هم؛ پایتون اصلاً نمی‌فهمد چه می‌خواهید و پیش از اجرای حتی یک خط، خطای SyntaxError می‌دهد.

print("hi"5)
SyntaxError: invalid syntax

خطاهای نحوی رایج‌ترین خطاها هستند ولی خوشبختانه ساده‌ترین هم هستند، چون پایتون دقیقاً محلشان را نشان می‌دهد: پرانتز یا کوتیشن بسته‌نشده، فراموش کردن : بعد از if، تورفتگی (indentation) اشتباه.

۲. معنای ایستا (Static Semantics)

جمله از نظر دستوری درست است، ولی معنی ندارد.

  • فارسی: «او مهربان بودم». ساختار جمله درست است، ولی فاعل سوم‌شخص با فعل اول‌شخص جور نیست.
  • پایتون: "hi" + 3. شکل عبارت درست است (چیزی + چیزی)، ولی جمع کردن رشته با عدد تعریف نشده است.
print("hi" + 3)

دکمهٔ «اجرا» را بزنید. پایتون خطای TypeError می‌دهد: «فقط می‌توانم str را به str بچسبانم، نه int را».

💡 بعضی زبان‌ها (مثل جاوا و C++‎) این نوع خطا را قبل از اجرا می‌گیرند. پایتون بیشترشان را هنگام اجرا می‌فهمد، یعنی وقتی به همان خط برسد. پس ممکن است برنامه تا نیمه درست کار کند و بعد بایستد.

۳. معنا (Semantics)

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

در زبان فارسی یک جمله ممکن است چند معنی داشته باشد. جملهٔ معروف «عفو لازم نیست اعدامش کنید» بسته به جای ویرگول دو معنای کاملاً متضاد دارد. در زبان برنامه‌نویسی هر عبارت معتبر دقیقاً یک معنا دارد؛ ولی ممکن است آن معنا با منظور برنامه‌نویس یکی نباشد.

مثال: می‌خواهیم میانگین دو نمره را حساب کنیم:

a = 18
b = 14
average = a + b / 2
print(average)

خروجی 25.0 است، نه 16! چون پایتون ضرب و تقسیم را قبل از جمع انجام می‌دهد. نتیجه: a + (b / 2). کامپیوتر اشتباه نکرده؛ دقیقاً همان چیزی را اجرا کرده که نوشته‌ایم. درستش:

a = 18
b = 14
average = (a + b) / 2
print(average)

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

وقتی خطای معنایی (منطقی) داریم، یکی از این سه اتفاق می‌افتد:

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

برای همین برنامه‌نویس‌های باتجربه کدشان را با چند ورودی که جوابشان را از قبل می‌دانند تست می‌کنند.

چطور پیام خطا را بخوانیم؟

پیام خطای پایتون را از پایین به بالا بخوانید:

Traceback (most recent call last):
  File "main.py", line 3, in <module>
    print("Age: " + age)
TypeError: can only concatenate str (not "int") to str
  • خط آخر نوع خطا (TypeError) و توضیحش را می‌گوید.
  • بالاتر دقیقاً نشان می‌دهد در کدام فایل و کدام خط (line 3) اتفاق افتاده.
نوع خطا معمولاً یعنی
SyntaxError دستور زبان رعایت نشده (پرانتز، کوتیشن، دونقطه)
IndentationError تورفتگی خطوط درست نیست
NameError از متغیری استفاده کرده‌اید که تعریف نشده (یا املایش فرق دارد)
TypeError عملیات روی نوع داده‌ای که پشتیبانی‌اش نمی‌کند
ValueError نوع درست است ولی مقدار نه، مثل int("salam")
ZeroDivisionError تقسیم بر صفر

💡 عادت حرفه‌ای: پیام خطا را کپی کنید و جست‌وجو کنید. تقریباً هر خطایی که به آن برمی‌خورید، قبلاً هزاران نفر دیده‌اند و جوابش موجود است.

تمرین

هر کدام از این‌ها کدام نوع خطاست؟ اول فکر کنید، بعد کد را اجرا کنید.

x = 10
print("x is " + x)
جواب

معنای ایستا (TypeError): چسباندن رشته به عدد. درستش: print("x is " + str(x)) یا print("x is", x).

celsius = 30
fahrenheit = celsius * 9 / 5 + 23
print(fahrenheit)
جواب

خطای معنایی (منطقی): برنامه اجرا می‌شود ولی فرمول اشتباه است. باید + 32 باشد. هیچ پیام خطایی هم نمی‌بینید!