وبلاگ نت‌آرامآموزش، تجربه و راهکارهای زیرساخت

رفع خطای circular import در Flask؛ برنامه را بدون وابستگی چرخشی اجرا کنیم

آموزش پیدا کردن چرخه import در Flask و ساخت برنامه آزمایشی با application factory و blueprint.

انتشار:
توسط تیم فنی نت‌آرام
۶ دقیقه زمان مطالعه
۰ دیدگاه
محتوای تخصصی، ساده و کاربردی
هماهنگ با هویت حرفه‌ای نت‌آرام
بازگشت به لیست مقالات
تصویر شاخص مقاله رفع خطای circular import در Flask؛ برنامه را بدون وابستگی چرخشی اجرا کنیم در وبلاگ نت‌آرام
محتوای آموزشی وبلاگ نت‌آرام
برنامه Flask هنگام شروع پیام cannot import name ... from partially initialized module می‌دهد. این خطا اغلب وقتی دیده می‌شود که فایل اول در حال بارگذاری فایل دوم است و فایل دوم، پیش از پایان کار فایل اول، دوباره چیزی از همان فایل اول می‌خواهد. مانند دو نفر که هر کدام منتظر تمام شدن کار دیگری هستند، ساخت برنامه به بن‌بست می‌رسد.
در این راهنما ابتدا مسیر import را از روی خطا می‌خوانیم. سپس یک نمونه کوچک با application factory می‌سازیم، آن را در ترمینال آزمایش می‌کنیم و در پایان توضیح می‌دهیم چطور تغییر را با احتیاط وارد پروژه اصلی کنیم.

۱. قبل از تغییر کد، مسیر خطا را بخوانید

در Terminal یا SSH به پوشه آزمایشی پروژه بروید و همان محیط پایتون برنامه را فعال کنید. اگر پنل فرمان فعال‌سازی جداگانه دارد، از همان استفاده کنید:
کد / دستورcd ~/flask-test pwd python --version python -c "import sys; print(sys.executable)"
به جای مسیر نمونه، پوشه واقعی کپی آزمایشی را بگذارید. گزارش کامل خطا معمولاً چند خط File ... line ... دارد. نام فایل‌ها و importهایی را که به هم برمی‌گردند روی کاغذ یادداشت کنید. برای نمونه، app.py از views.py چیزی می‌گیرد و views.py نیز در همان ابتدای فایل app را از app.py می‌خواهد. پیش از ارسال گزارش، مسیرهای خصوصی و رمزها را حذف کنید.
گاهی علت چرخه نیست: نام فایل شما flask.py یا نام یک بسته نصب‌شده است و پایتون همان فایل محلی را به جای کتابخانه بارگذاری می‌کند. نام فایل و پوشه‌ها را بررسی کنید. تغییر نام را ابتدا روی نسخه آزمایشی انجام دهید و importهای وابسته را نیز هماهنگ کنید؛ فایل فعال را بدون برنامه جابه‌جا نکنید.

۲. یک نمونه سالم و کوچک بسازید

این مثال آموزشی فقط به Flask نیاز دارد و قرار نیست جای کل پروژه شما را بگیرد. ساختار زیر را در پوشه جدید و آزمایشی بسازید:
کد / دستورflask-test/ myapp/ __init__.py views.py wsgi.py
در فایل myapp/__init__.py بنویسید:
کد / دستورfrom flask import Flask def create_app(): app = Flask(__name__) app.config["SITE_NAME"] = "Demo" from .views import pages app.register_blueprint(pages) return app
در فایل myapp/views.py بنویسید:
کد / دستورfrom flask import Blueprint, current_app pages = Blueprint("pages", __name__) @pages.route("/") def home(): return "Hello " + current_app.config["SITE_NAME"]
اینجا فایل views دیگر شیء app را از فایل سازنده import نمی‌کند. current_app داخل تابع درخواست به برنامه جاری دسترسی می‌دهد. خارج از زمینه برنامه یا درخواست، استفاده از آن می‌تواند خطای Working outside of application context بدهد؛ بنابراین آن را در سطح بالای فایل برای خواندن تنظیمات فراخوانی نکنید.
در wsgi.py بنویسید:
کد / دستورfrom myapp import create_app application = create_app()
نام application نمونه رایج WSGI است. پنل شما ممکن است نام فایل یا شیء دیگری بخواهد؛ راهنمای سرویس را تطبیق دهید و فایل شروع موجود را قبل از تغییر نگه دارید.

۳. نمونه را بدون باز کردن سایت عمومی آزمایش کنید

در پوشه دارای wsgi.py و با محیط پایتون پروژه اجرا کنید:
کد / دستورpython -c "from myapp import create_app; app = create_app(); print(app.url_map)" python -c "from myapp import create_app; app = create_app(); print(app.test_client().get('/').get_data(as_text=True))"
دستور اول باید مسیر / را در نقشه مسیرها نشان دهد و دومی برای همین مثال عبارت Hello Demo را چاپ کند. اگر No module named flask دیدید، ابتدا محیط و وابستگی‌ها را طبق راهنمای ModuleNotFoundError درست کنید. اگر ماژول myapp پیدا نشد، محل اجرای دستور و وجود __init__.py را ببینید.

۴. ساختار را با پروژه واقعی تطبیق دهید

در کپی پروژه، بخش ساخت برنامه را داخل تابعی مانند create_app ببرید و مسیرها را با Blueprint ثبت کنید. برای افزونه‌هایی مانند اتصال پایگاه داده، معمولاً شیء افزونه جداگانه ساخته و سپس با init_app(app) به برنامه وصل می‌شود؛ روش دقیق به مستندات همان افزونه بستگی دارد. تنظیمات، کلیدهای محرمانه، اتصال‌ها و وظایف پس‌زمینه پروژه واقعی را حذف نکنید.
کپی‌کردن چند خط نمونه بدون انتقال درست تنظیمات یا ترتیب ثبت route می‌تواند سایت را از کار بیندازد. پس هر تغییر کوچک را با آزمون‌های پروژه، import برنامه و درخواست آزمایشی بررسی کنید. اگر چرخه بین دو فایل ابزار یا مدل است، انتقال تابع مشترک به یک ماژول مستقل و کم‌وابستگی نیز می‌تواند راه مناسب‌تری باشد؛ factory پاسخ همه چرخه‌ها نیست.

۵. ورود WSGI و اجرای سایت را دوباره بسنجید

پس از موفقیت آزمون محلی، نسخه آزمایشی را با همان تنظیم پنل و محیط پایتون اجرا کنید. گزارش راه‌اندازی، صفحه اصلی و مسیری که قبلاً خطا می‌داد را بررسی کنید. تا اطمینان از نسخه جدید، نسخه قبلی و تنظیم فایل شروع را برای بازگشت نگه دارید. اگر import در ترمینال درست است اما پنل شکست می‌خورد، مسیر ریشه برنامه و فایل WSGI را با راهنمای راه‌اندازی Passenger مقایسه کنید.
اگر پس از جابه‌جایی کد خطای «خارج از زمینه برنامه» دریافت می‌کنید، ببینید آیا کدی که از current_app استفاده می‌کند واقعاً هنگام رسیدگی به درخواست اجرا می‌شود یا در زمان import فایل. برای تابع مستقل یا دستور خط فرمان، در صورت نیاز باید زمینه همان برنامه را به‌شکل آگاهانه با app.app_context() ایجاد کنید؛ انتقال دسترسی به درون تابع، در بسیاری از مسیرهای وب کافی است. ساختن چند برنامه مجزا فقط برای حذف خطا می‌تواند تنظیمات و اتصال‌های متفاوتی ایجاد کند.
اگر پیام هنوز partially initialized module است، متن traceback جدید را دوباره از ابتدا دنبال کنید؛ ممکن است چرخه دیگری بین مدل‌ها یا افزونه‌ها باقی مانده باشد. تغییر نام تصادفی بسته‌ها یا پاک‌کردن همه فایل‌های محیط مجازی جای تشخیص مسیر import را نمی‌گیرد. پس از اصلاح، هم import و هم درخواست واقعی را مجدداً آزمایش کنید.
امکانات هاست پایتون نت‌آرام و توضیح الگوی ساخت برنامه در مستندات Flask در دسترس است.
اشتراک‌گذاری:
لینکدینتلگرامایکس
مقاله قبلی
مقاله قبلی وجود ندارد.

دیدگاه‌ها (۰)

دیدگاه‌های تاییدشده و پاسخ‌های تیم نت‌آرام