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

خطای ‘int’ object is not subscriptable در پایتون؛ معنی و رفع

خطای 'int' object is not subscriptable در پایتون؛ معنی و رفع

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

پیام TypeError: 'int' object is not subscriptable یعنی روی مقداری از براکت [] استفاده کرده‌اید که از ایندکس‌گذاری پشتیبانی نمی‌کند. «Subscriptable» یعنی شیئی که بتوان با [ ] به اجزایش دسترسی داشت؛ مثل لیست، رشته، تاپل و دیکشنری. عدد، None و تابع این قابلیت را ندارند.

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

وقتی می‌نویسید x[0]، پایتون از شیء x می‌خواهد عضو شماره صفرش را بدهد. اگر x عدد صحیح باشد، اصلاً «عضوی» ندارد و خطای not subscriptable رخ می‌دهد. همین خطا با نوع‌های دیگر هم دیده می‌شود: 'NoneType' object is not subscriptable (متغیر None است) و 'function' object is not subscriptable یا برای توابع داخلی مثل len پیام 'builtin_function_or_method' object is not subscriptable (پرانتز تابع را فراموش کرده‌اید یا به جای پرانتز از براکت استفاده کرده‌اید).

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

  • تلاش برای گرفتن رقم یک عدد با ایندکس، مثل number[0].
  • بازنویسی ناخواسته متغیر لیست با یک عدد در طول برنامه.
  • کار با خروجی تابعی که None برمی‌گرداند.
  • استفاده از براکت به جای پرانتز برای صدا زدن تابع، مثل len[items].

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

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

مثال 1: گرفتن رقم اول یک عدد

❌ کد غلط:

number = 2026
print(number[0])

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    print(number[0])
          ~~~~~~^^^
TypeError: 'int' object is not subscriptable

✅ کد درست:

number = 2026
print(str(number)[0])
print(int(str(number)[0]) + 1)

خروجی:

2
3

مثال 2: متغیری که None است

❌ کد غلط:

def find_user(name):
    if name == "ali":
        return ["ali", 30]

user = find_user("sara")
print(user[0])

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 6, in <module>
    print(user[0])
          ~~~~^^^
TypeError: 'NoneType' object is not subscriptable

✅ کد درست:

def find_user(name):
    if name == "ali":
        return ["ali", 30]
    return None

user = find_user("sara")
if user is not None:
    print(user[0])
else:
    print("User not found")

خروجی:

User not found

مثال 3: براکت به جای پرانتز

❌ کد غلط:

items = [1, 2, 3]
print(len[items])

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 2, in <module>
    print(len[items])
          ~~~^^^^^^^
TypeError: 'builtin_function_or_method' object is not subscriptable

✅ کد درست:

items = [1, 2, 3]
print(len(items))

خروجی:

3

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

  1. نوع شیء را از پیام خطا بخوانید (int، NoneType، function و…).
  2. با print(type(x), x) درست قبل از خط خطا، مقدار واقعی متغیر را ببینید.
  3. اگر عدد است و به ارقامش نیاز دارید، ابتدا آن را با str() به رشته تبدیل کنید.
  4. اگر None است، بررسی کنید تابع یا متد قبلی چرا چیزی برنگردانده است.
  5. اگر function است، براکت را به پرانتز تبدیل کنید یا پرانتز صدا زدن را اضافه کنید.

خواندن پیام object is not subscriptable و عیب‌یابی

Subscript یعنی استفاده از کروشه بعد از یک مقدار، مثل x[0] یا data['name']. فقط اشیایی که متد __getitem__ دارند، مثل لیست، رشته، تاپل و دیکشنری، از این نحو پشتیبانی می‌کنند. وقتی روی عدد صحیح، None، تابع یا شیء دیگری کروشه بگذارید، پایتون TypeError با پیام object is not subscriptable می‌دهد و نوع آن شیء را داخل کوتیشن ذکر می‌کند.

کلید حل مسئله همان نوعی است که در پیام آمده: 'int'، 'NoneType'، 'function' یا 'method'. اگر NoneType است، یعنی تابعی که انتظار داشتید لیست برگرداند چیزی برنگردانده؛ اگر function است، احتمالاً پرانتز فراخوانی را فراموش کرده‌اید. با type() و print درست قبل از خط خطا، نوع واقعی متغیر را ببینید.

سه علت رایج در یک نگاه

def get_scores():
    scores = [90, 75, 60]
    scores.sort()

cases = [
    ("int", lambda: (12345)[0]),
    ("None", lambda: get_scores()[0]),
    ("function", lambda: len[0]),
]

for label, func in cases:
    try:
        func()
    except TypeError as error:
        print(label, "->", error)

print("digit:", str(12345)[0])

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

int -> 'int' object is not subscriptable
None -> 'NoneType' object is not subscriptable
function -> 'builtin_function_or_method' object is not subscriptable
digit: 1

قدم‌به‌قدم رفع not subscriptable

نوعی که داخل کوتیشن پیام آمده، مستقیم علت را نشان می‌دهد.

  1. نوع ذکرشده را بخوانید: ‘int’، ‘NoneType’، ‘function’ یا ‘method’ هرکدام راه‌حل متفاوتی دارند.
  2. منبع مقدار را دنبال کنید: ببینید متغیر آخرین بار کجا مقدار گرفته؛ اگر از تابع آمده، بررسی کنید return دارد یا نه.
  3. پرانتز فراموش‌شده را چک کنید: اگر نوع function یا method است، احتمالاً به جای obj.items()[0] نوشته‌اید obj.items[0].
  4. متدهای درجا را بشناسید: sort، append و reverse مقدار None برمی‌گردانند؛ نتیجه آن‌ها را در متغیر نریزید.
  5. تبدیل مناسب انجام دهید: برای عدد از str(n)[i] و برای مجموعه از list(s)[i] استفاده کنید.

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

  • قبل از ایندکس‌گذاری، نوع داده را با isinstance بررسی کنید یا type hint بنویسید.
  • مطمئن شوید تابع‌ها با return مقدار برمی‌گردانند؛ متدهایی مثل sort و append مقدار None برمی‌گردانند.
  • برای دسترسی به رقم‌های یک عدد، اول آن را با str به رشته تبدیل کنید.
  • نام متغیرها را طوری انتخاب کنید که با نام توابع داخلی مثل list یا len تداخل نداشته باشد.
  • از ابزار بررسی نوع مثل mypy استفاده کنید تا این خطا پیش از اجرا پیدا شود.

📌 همچنین بخوانید: خطای unexpected EOF while parsing در پایتون، خطای ImportError و خطای RecursionError در پایتون

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

subscriptable یعنی چه؟

یعنی شیء متد __getitem__ را دارد و می‌توان با obj[index] یا obj[key] به اجزایش دسترسی پیدا کرد؛ مثل list، str، tuple و dict.

فرق این خطا با IndexError چیست؟

در IndexError شیء قابل ایندکس است ولی ایندکس خارج از محدوده است؛ در not subscriptable اصلاً ایندکس‌گذاری روی آن نوع معنا ندارد.

چطور ‘NoneType’ object is not subscriptable را رفع کنم؟

مقداری که None شده را ردیابی کنید؛ اغلب از متدهایی مثل sort() یا توابعی بدون return می‌آید. قبل از استفاده is not None را بررسی کنید.

NoneType object is not subscriptable یعنی چه؟

یعنی متغیری که روی آن کروشه گذاشته‌اید مقدار None دارد؛ معمولاً چون تابع یا متدی مثل sort چیزی برنگردانده یا جست‌وجویی نتیجه‌ای نداشته است.

چطور یک کلاس را subscriptable کنم؟

کافی است متد __getitem__ را در کلاس تعریف کنید تا اشیای آن از نحو obj[key] پشتیبانی کنند.

فرق این خطا با object is not iterable چیست؟

not subscriptable مربوط به کروشه است و not iterable مربوط به حلقه for یا باز کردن مقادیر؛ هر دو یعنی شیء از آن عملیات پشتیبانی نمی‌کند.

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

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

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

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