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

خطای ValueError در پایتون؛ invalid literal for int() with base 10

خطای ValueError در پایتون؛ invalid literal for int() with base 10

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

فرض کنید از کاربر سنش را می‌پرسید و او به جای عدد می‌نویسد «بیست». وقتی این ورودی را با int() به عدد تبدیل می‌کنید، با خطای ValueError: invalid literal for int() with base 10 روبه‌رو می‌شوید. این خطا در برنامه‌هایی که ورودی کاربر یا داده فایل را پردازش می‌کنند بسیار رایج است.

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

ValueError یعنی تابعی آرگومانی با نوع درست دریافت کرده، اما مقدار آن آرگومان قابل قبول نیست. مثلاً int() رشته می‌پذیرد، ولی فقط رشته‌ای که شکل یک عدد صحیح را داشته باشد. نکته جالب: پایتون ارقام فارسی را هم می‌شناسد و int("۲۵") عدد ۲۵ را برمی‌گرداند؛ اما متن، اعشار یا فاصله‌های داخلی باعث ValueError می‌شوند.

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

  • تبدیل متن غیرعددی به عدد با int() یا float().
  • تبدیل مستقیم عدد اعشاری به صورت رشته با int()، مثل int("3.5").
  • باز کردن (Unpacking) لیستی با تعداد عضو متفاوت از تعداد متغیرها.
  • پیدا نکردن مقدار با list.remove() یا list.index().
  • داده‌های خالی یا ناقص در فایل‌های CSV و ورودی‌ها.

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

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

مثال 1: تبدیل متن به عدد

❌ کد غلط:

age = int("twenty")
print(age)

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 1, in <module>
    age = int("twenty")
ValueError: invalid literal for int() with base 10: 'twenty'

✅ کد درست:

text = "twenty"
try:
    age = int(text)
except ValueError:
    age = 0
    print("Please enter your age as a number")
print(age)

خروجی:

Please enter your age as a number
0

مثال 2: رشته اعشاری با int()

❌ کد غلط:

price = int("3.5")

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 1, in <module>
    price = int("3.5")
ValueError: invalid literal for int() with base 10: '3.5'

✅ کد درست:

price = int(float("3.5"))
print(price)

خروجی:

3

مثال 3: باز کردن با تعداد نابرابر

❌ کد غلط:

name, age = ["Sara", 25, "Tehran"]

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 1, in <module>
    name, age = ["Sara", 25, "Tehran"]
    ^^^^^^^^^
ValueError: too many values to unpack (expected 2)

✅ کد درست:

name, age, city = ["Sara", 25, "Tehran"]
print(name, age, city)

خروجی:

Sara 25 Tehran

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

  1. در پیام خطا مقدار مشکل‌دار را (که داخل کوتیشن آمده) پیدا کنید.
  2. بررسی کنید این مقدار از کجا آمده است: ورودی کاربر، فایل یا محاسبه.
  3. قبل از تبدیل، با .strip() فاصله‌های اضافه را حذف کنید و در صورت نیاز با .isdigit() عددی بودن را بسنجید.
  4. تبدیل را داخل try/except ValueError قرار دهید و پیام راهنمای مناسب نشان دهید.
  5. برای ورودی کاربر یک حلقه while بسازید تا تا وارد شدن مقدار معتبر دوباره سؤال شود.

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

ValueError یعنی نوع داده درست است ولی مقدار آن برای آن عملیات قابل قبول نیست. مثال کلاسیک int('abc') است: ورودی رشته است و int رشته قبول می‌کند، اما این رشته خاص عدد نیست. باز کردن مقادیر با تعداد نامناسب (too many values to unpack) و list.remove برای عضوی که وجود ندارد هم ValueError می‌دهند.

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

آشکار کردن کاراکترهای پنهان و تبدیل امن

raw = " 1,250\n"
print("repr:", repr(raw))

try:
    int(raw)
except ValueError as error:
    print(type(error).__name__, "-", error)

clean = raw.strip().replace(",", "")
print("Number:", int(clean))

try:
    a, b = [1, 2, 3]
except ValueError as error:
    print(type(error).__name__, "-", error)

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

repr: ' 1,250\n'
ValueError - invalid literal for int() with base 10: ' 1,250\n'
Number: 1250
ValueError - too many values to unpack (expected 2)

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

مقدار مشکل‌دار داخل پیام آمده؛ آن را دقیق بررسی کنید.

  1. مقدار پیام را بخوانید: بخش بعد از دونقطه، مثل ‘twenty’ یا ‘ 12\n’، دقیقاً همان ورودی ناموفق است.
  2. با repr چاپ کنید: کاراکترهای پنهان مثل \n، فاصله، ویرگول هزارگان یا رقم فارسی فقط با repr دیده می‌شوند.
  3. نوع ValueError را تشخیص دهید: invalid literal یعنی تبدیل ناموفق؛ too many values to unpack یعنی تعداد اعضا؛ not in list یعنی جست‌وجو.
  4. ورودی را تمیز کنید: strip، replace و تبدیل رقم‌های فارسی را قبل از int یا float انجام دهید.
  5. اعتبارسنجی کنید: تبدیل را در try/except ValueError قرار دهید و از کاربر دوباره ورودی بخواهید.

اگر برنامه شما ورودی فارسی می‌گیرد، توجه کنید که int رقم‌های فارسی یونیکد را می‌پذیرد، اما متن‌هایی مثل «بیست» یا عدد با جداکننده فارسی را نمی‌پذیرد. پس اعتبارسنجی را با پیام واضح انجام دهید. برای تبدیل مطمئن، ابتدا ورودی را با str.isdigit بررسی کنید و در غیر این صورت راهنمای کوتاهی نشان دهید.

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

  • ورودی کاربر را قبل از تبدیل با strip تمیز کنید.
  • تبدیل‌ها را داخل try/except ValueError قرار دهید و پیام مناسب نشان دهید.
  • برای رقم‌های فارسی و عربی، قبل از int آن‌ها را به رقم انگلیسی تبدیل کنید.
  • هنگام unpack، تعداد اعضا را بررسی کنید یا از *rest استفاده کنید.
  • برای اعداد اعشاری از float و برای پول از decimal.Decimal استفاده کنید.

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

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

فرق ValueError با TypeError چیست؟

TypeError یعنی نوع داده اشتباه است (مثلاً لیست به int)، اما ValueError یعنی نوع درست است ولی مقدار نامعتبر است (مثلاً رشته «abc» به int).

آیا int() ارقام فارسی را می‌پذیرد؟

بله. پایتون ارقام یونیکد را می‌شناسد و int("۱۴۰۵") عدد 1405 را برمی‌گرداند. اما ممیز فارسی «٫» را به‌عنوان اعشار نمی‌شناسد.

چطور ورودی کاربر را تا وارد شدن عدد درست تکرار کنم؟

از الگوی while True همراه با try/except ValueError استفاده کنید و در صورت موفقیت با break از حلقه خارج شوید.

فرق ValueError و TypeError چیست؟

TypeError یعنی نوع داده اشتباه است، مثل جمع عدد و رشته؛ ValueError یعنی نوع درست است ولی مقدار نامعتبر است، مثل int('abc').

چرا int('3.5') خطا می‌دهد؟

int رشته اعشاری را قبول نمی‌کند؛ اول float('3.5') و بعد int را بزنید.

خودم کی باید ValueError ایجاد کنم؟

وقتی تابع شما آرگومانی با نوع درست ولی مقدار غیرمجاز دریافت می‌کند، مثل سن منفی؛ با raise ValueError پیام روشن بدهید.

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

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

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

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