رفع خطاهای پایتون

خطای ZeroDivisionError در پایتون؛ division by zero و روش جلوگیری

خطای ZeroDivisionError در پایتون؛ division by zero و روش جلوگیری

🗓 آخرین به‌روزرسانی:

در ریاضی تقسیم بر صفر تعریف نشده است و پایتون هم همین قاعده را رعایت می‌کند. اگر عددی را بر صفر تقسیم کنید (با /، // یا %)، خطای ZeroDivisionError می‌گیرید. این خطا معمولاً در محاسبه میانگین لیست خالی یا ورودی صفر کاربر پیش می‌آید.

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

ZeroDivisionError یعنی مقسوم‌علیه (عدد سمت راست عملگر تقسیم یا باقیمانده) برابر صفر بوده است. پیام آن بسته به عملیات کمی فرق می‌کند؛ مثلاً division by zero برای تقسیم و integer modulo by zero برای باقیمانده اعداد صحیح. این خطا در زمان اجرا رخ می‌دهد و با بررسی ساده قبل از تقسیم قابل پیشگیری است.

علت‌های رایج این خطا

  • محاسبه میانگین لیست خالی (sum([]) / len([])).
  • ورودی صفر از سمت کاربر.
  • متغیری که در شرایط خاص صفر می‌شود (مثل تعداد آیتم‌ها).
  • استفاده از % برای بخش‌پذیری با مقسوم‌علیه صفر.

کد غلط و کد درست (با خروجی واقعی)

همه نمونه‌کدهای زیر با پایتون 3.13.5 اجرا شده‌اند و خروجی‌ها همان چیزی است که پایتون واقعاً نمایش می‌دهد.

مثال 1: میانگین لیست خالی

❌ کد غلط:

scores = []
average = sum(scores) / len(scores)
print(average)

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    average = sum(scores) / len(scores)
              ~~~~~~~~~~~~^~~~~~~~~~~~~
ZeroDivisionError: division by zero

✅ کد درست:

scores = []
average = sum(scores) / len(scores) if scores else 0
print(average)

خروجی:

0

مثال 2: مدیریت ورودی صفر با try/except

❌ کد غلط:

a, b = 10, 0
print(a / b)

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    print(a / b)
          ~~^~~
ZeroDivisionError: division by zero

✅ کد درست:

a, b = 10, 0
try:
    print(a / b)
except ZeroDivisionError:
    print("Cannot divide by zero")

خروجی:

Cannot divide by zero

مثال 3: باقیمانده بر صفر

❌ کد غلط:

n = 0
print(10 % n)

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    print(10 % n)
          ~~~^~~
ZeroDivisionError: integer modulo by zero

✅ کد درست:

n = 0
if n != 0:
    print(10 % n)
else:
    print("The divisor is zero")

خروجی:

The divisor is zero

راه‌حل قدم‌به‌قدم

  1. خطی که تقسیم یا باقیمانده در آن انجام شده را پیدا کنید.
  2. مقدار مقسوم‌علیه را قبل از آن خط چاپ کنید و ببینید چرا صفر شده است.
  3. پیش از تقسیم با if b != 0 یا if items بررسی کنید.
  4. برای ورودی کاربر، صفر را جزو مقادیر نامعتبر در نظر بگیرید و دوباره سؤال کنید.
  5. در جایی که صفر شدن ممکن ولی نادر است، از try/except ZeroDivisionError استفاده کنید.

خواندن پیام ZeroDivisionError و عیب‌یابی

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

در traceback ببینید کدام متغیر مخرج کسر است و از کجا مقدار گرفته است. رایج‌ترین مورد محاسبه میانگین لیست خالی است: sum(items) / len(items). تصمیم بگیرید در این حالت چه نتیجه‌ای منطقی است: صفر، None یا پیام خطا. کد زیر هر دو رویکرد بررسی شرط و try/except را نشان می‌دهد.

محاسبه امن میانگین

def average(values):
    if not values:
        return None
    return sum(values) / len(values)

print("Average:", average([10, 20, 30]))
print("Empty:", average([]))

for op in ("/", "//", "%"):
    try:
        eval(f"5 {op} 0")
    except ZeroDivisionError as error:
        print(op, "->", error)

print("float:", 5.0 / 2)

خروجی (اجراشده با Python 3.13):

Average: 20.0
Empty: None
/ -> division by zero
// -> integer division or modulo by zero
% -> integer modulo by zero
float: 2.5

قدم‌به‌قدم رفع ZeroDivisionError

خط خطا مشخص است؛ سؤال اصلی این است که مخرج از کجا صفر شده.

  1. مخرج را شناسایی کنید: در خط گزارش‌شده، متغیر بعد از /، // یا % را پیدا کنید.
  2. منبع صفر را دنبال کنید: آیا از len یک لیست خالی، ورودی کاربر یا شمارنده‌ای که افزایش نیافته آمده است؟
  3. نوع عملگر را ببینید: پیام division by zero، integer modulo by zero یا float division by zero نوع عملیات را مشخص می‌کند.
  4. رفتار درست را تعیین کنید: در حالت صفر باید 0، None، float(‘inf’) یا پیام خطا برگردد؟ این یک تصمیم منطقی است، نه فنی.
  5. نگهبان بگذارید: شرط if divisor یا try/except را دقیقاً قبل از تقسیم قرار دهید و حالت صفر را تست کنید.

در کدهای آماری مثل محاسبه درصد پیشرفت، میانگین نمره یا نرخ تبدیل، صفر بودن مخرج یک حالت کاملاً عادی است؛ مثلاً روزی که هیچ بازدیدی ثبت نشده. این حالت را از ابتدا در طراحی تابع ببینید و برایش تست بنویسید. همچنین در گزارش‌ها به جای نمایش خطا، مقدار «بدون داده» را به کاربر نشان دهید تا خروجی برنامه قابل فهم بماند و اعتماد کاربر حفظ شود.

چک‌لیست پیشگیری

  • قبل از تقسیم، مقسوم‌علیه را بررسی کنید؛ مخصوصاً وقتی از ورودی کاربر یا len می‌آید.
  • برای لیست‌های خالی رفتار مشخصی تعریف کنید و آن را مستند کنید.
  • در محاسبات اعشاری، به جای مقایسه با صفر دقیق از math.isclose استفاده کنید.
  • ورودی‌های کاربر را با حلقه و پیام مناسب اعتبارسنجی کنید.
  • در pandas و numpy تقسیم بر صفر خطا نمی‌دهد و inf یا nan تولید می‌کند؛ نتیجه را بررسی کنید.

📌 همچنین بخوانید: خطای unexpected EOF while parsing در پایتون، خطای ‘int’ object is not subscriptable در پایتون و خطای ImportError

سؤالات متداول

آیا تقسیم اعشاری بر صفر هم خطا می‌دهد؟

بله؛ 1.0 / 0 در پایتون معمولی هم ZeroDivisionError می‌دهد. فقط کتابخانه‌هایی مثل NumPy به جای خطا مقدار inf و یک هشدار برمی‌گردانند.

بهتر است از if استفاده کنم یا try/except؟

اگر صفر بودن یک حالت قابل انتظار است (مثل لیست خالی) if خواناتر است؛ اگر استثنایی و نادر است، try/except مناسب‌تر است.

تقسیم صفر بر یک عدد خطا دارد؟

خیر؛ 0 / 5 کاملاً معتبر است و نتیجه‌اش 0.0 است. فقط تقسیم «بر» صفر مشکل دارد.

چرا در numpy تقسیم بر صفر خطا نمی‌دهد؟

numpy طبق استاندارد IEEE نتیجه inf یا nan برمی‌گرداند و فقط هشدار می‌دهد؛ پایتون خالص اما ZeroDivisionError ایجاد می‌کند.

try/except بهتر است یا if؟

اگر صفر بودن حالت عادی و قابل انتظار است، if خواناتر است؛ اگر نادر و استثنایی است، try/except مناسب‌تر است.

آیا 0.0 هم خطا می‌دهد؟

بله، تقسیم بر 0.0 در پایتون هم ZeroDivisionError با پیام float division by zero ایجاد می‌کند.

آموزش‌های مرتبط

آموزش‌های تازه، کد آماده و رفع خطاهر هفته در کانال Dev Source؛ رایگان.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *