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

خطای ImportError: cannot import name در پایتون؛ علت و رفع

خطای ImportError: cannot import name در پایتون؛ علت و رفع

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

پیام ImportError: cannot import name 'X' from 'Y' با ModuleNotFoundError فرق دارد: اینجا پایتون ماژول Y را پیدا کرده، اما نامی که با from Y import X خواسته‌اید داخل آن نیست. علت می‌تواند یک غلط تایپی ساده، تغییر نام تابع در نسخه جدید کتابخانه یا import حلقوی بین دو فایل باشد.

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

دستور from module import name ابتدا ماژول را بارگذاری می‌کند و سپس دنبال name داخل آن می‌گردد. اگر آن نام تعریف نشده باشد، یا هنوز تعریف نشده باشد (در import حلقوی)، ImportError رخ می‌دهد. پایتون در پیام خطا مسیر فایل ماژول را هم نشان می‌دهد که برای تشخیص فایل‌های هم‌نام بسیار مفید است.

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

  • غلط تایپی در نام تابع یا کلاس.
  • تغییر یا حذف نام در نسخه جدید یک کتابخانه.
  • Import حلقوی: فایل a.py از b.py و b.py هم از a.py چیزی import می‌کند.
  • وجود فایلی هم‌نام با ماژول در پوشه پروژه که به جای ماژول اصلی بارگذاری می‌شود.

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

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

مثال 1: نام اشتباه از ماژول استاندارد

❌ کد غلط:

from math import squareroot
print(squareroot(9))

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 1, in <module>
    from math import squareroot
ImportError: cannot import name 'squareroot' from 'math' (unknown location)

✅ کد درست:

from math import sqrt
print(sqrt(9))

خروجی:

3.0

مثال 2: بررسی نام‌های موجود در ماژول

❌ کد غلط:

from random import randomint

خروجی:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 1, in <module>
    from random import randomint
ImportError: cannot import name 'randomint' from 'random' (/usr/lib/python3.13/random.py). Did you mean: 'randint'?

✅ کد درست:

import random
print([n for n in dir(random) if "rand" in n])

خروجی:

['_random', '_urandom', 'getrandbits', 'randbytes', 'randint', 'random', 'randrange']

رفع import حلقوی (Circular Import)

اگر پیام خطا عبارت partially initialized module یا most likely due to a circular import را دارد، دو فایل همدیگر را import می‌کنند. راه‌حل‌ها: کد مشترک را به فایل سوم منتقل کنید، import را به داخل تابعی که به آن نیاز دارد ببرید، یا به جای from b import func از import b و b.func() استفاده کنید.

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

  1. نام خواسته‌شده و مسیر ماژول را در پیام خطا بخوانید.
  2. با dir(module) یا مستندات، نام درست تابع یا کلاس را پیدا کنید.
  3. مسیر نمایش داده‌شده را بررسی کنید؛ اگر به فایلی در پروژه خودتان اشاره دارد، آن را تغییر نام دهید.
  4. نسخه کتابخانه را با python -m pip show نام-بسته ببینید و با مستندات همان نسخه مقایسه کنید.
  5. در صورت import حلقوی، ساختار فایل‌ها را طبق توضیح بالا اصلاح کنید.

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

ImportError وقتی رخ می‌دهد که ماژول پیدا شده ولی نامی که از آن خواسته‌اید در دسترس نیست، یا بارگذاری ماژول نیمه‌کاره مانده است. پیام رایج آن cannot import name است. برخلاف ModuleNotFoundError که یعنی کل ماژول پیدا نشده، اینجا مشکل در محتوای ماژول، نسخه کتابخانه یا ترتیب import هاست.

سه علت اصلی را به ترتیب بررسی کنید: املای نام و حروف بزرگ و کوچک، نسخه کتابخانه (نامی که در نسخه جدید حذف یا جابه‌جا شده) و import چرخشی که دو فایل یکدیگر را صدا می‌زنند. پیام پایتون 3.13 اغلب مسیر فایل ماژول و حتی پیشنهاد Did you mean را نشان می‌دهد که سرنخ بسیار خوبی است.

دیدن پیام دقیق و نام‌های موجود ماژول

import math

try:
    from math import squareroot
except ImportError as error:
    print(type(error).__name__, "-", error.msg)

names = [name for name in dir(math) if name.startswith("sq")]
print("Available:", names)

from math import sqrt
print("sqrt(16) =", sqrt(16))

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

ImportError - cannot import name 'squareroot' from 'math' (unknown location)
Available: ['sqrt']
sqrt(16) = 4.0

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

ماژول پیدا شده؛ پس مشکل در نام، نسخه یا ترتیب import است.

  1. نام خواسته‌شده را بررسی کنید: بعد از cannot import name نام دقیق می‌آید؛ آن را با dir(module) مقایسه کنید.
  2. مسیر ماژول را ببینید: با print(module.__file__) مطمئن شوید ماژول واقعی بارگذاری شده، نه فایلی هم‌نام در پروژه شما.
  3. نسخه کتابخانه را چک کنید: با pip show نسخه را ببینید و در changelog بگردید که آن نام حذف یا جابه‌جا شده یا نه.
  4. import چرخشی را پیدا کنید: عبارت partially initialized module نشانه آن است؛ زنجیره import دو فایل را دنبال کنید.
  5. ساختار را اصلاح کنید: کد مشترک را به ماژول سوم ببرید یا import را داخل تابع منتقل کنید.

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

  • قبل از import، نام دقیق را در مستندات همان نسخه کتابخانه بررسی کنید.
  • نسخه کتابخانه‌ها را در requirements.txt ثبت کنید تا تغییرات ناگهانی API شما را غافلگیر نکند.
  • نام فایل‌های خودتان را مشابه کتابخانه‌های معروف (مثل random.py یا requests.py) نگذارید.
  • برای رفع import چرخشی، کد مشترک را به ماژول سوم منتقل کنید یا import را داخل تابع ببرید.
  • با pip show نام پکیج، نسخه و محل نصب را بررسی کنید.

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

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

فرق ImportError و ModuleNotFoundError چیست؟

ModuleNotFoundError یعنی ماژول پیدا نشد (نصب نیست یا نامش اشتباه است)؛ ImportError با پیام cannot import name یعنی ماژول هست ولی نام مورد نظر داخلش نیست.

چرا بعد از آپدیت کتابخانه این خطا را گرفتم؟

گاهی توابع در نسخه‌های جدید تغییر نام می‌دهند یا جابه‌جا می‌شوند. یادداشت‌های انتشار (Changelog) را بخوانید یا نسخه سازگار را نصب کنید.

import * این مشکل را حل می‌کند؟

خیر؛ from module import * فقط مشکل را پنهان می‌کند و کد را ناخوانا می‌سازد. نام درست را صریحاً import کنید.

cannot import name … partially initialized module یعنی چه؟

یعنی import چرخشی دارید یا نام فایل شما با ماژولی که import می‌کنید یکی است. فایل را تغییر نام دهید یا وابستگی را جدا کنید.

چرا کد روی سیستم دوستم کار می‌کند ولی روی سیستم من نه؟

احتمالاً نسخه کتابخانه متفاوت است. با pip show نسخه را مقایسه کنید و همان نسخه را با pip install name==version نصب کنید.

ImportError و ModuleNotFoundError چه رابطه‌ای دارند؟

ModuleNotFoundError زیرکلاس ImportError است؛ پس except ImportError هر دو را می‌گیرد.

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

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

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

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