سینتکس به ظاهر ساده پایتون می تواند برنامه نویسانی که از این زبان استفاده می کنند، علی الخصوص برنامه نویسان تازه کار، را دراستفاده مناسب از دستورات این زبان گیج کند. این گیجی می تواند باعث شود که از بعضی ریزه کاری های این زبان نادانسته رد شوند و از تمام قدرت این زبان استفاده نکنند. در قسمت گذشته به تا از این اشتباهات احتمالی پرداختیم. در این پست به اشتباه دیگر می پردازیم. فرض کنید که دو فایل a . py و b . py را داریم که در هرکدام دیگری را import می کنیم. به گونه ای که در a . py داشته باشیم: و در b . py داشته باشیم: حالااگر a . py را import کنیم، خواهیم داشت: شاید برای شما سوال باشد که در برنامه ما که وابستگی import به صورت یک حلقه بسته بود که از نظر عملی خطاست ( a وابسته به b و b وابسته به a ) ، چرا اروری به ما داده نشد؟ جواب شما این است که حضور یک حلقه بسته از وابستگی import به تنهایی باعث مشکلی در پایتون نخواهد شد. ولی با توجه به محلی که هر ماژول سعی می کند به محتویات ماژول دیگر دسترسی پیدا کند، این نوع از وابستگی ها می تواند مشکل زا باشد (اگر در قسمتی از کد که اجرا نمی شود باشد ممکن است باعث مشکل نشود) در مثال وقتی که ما a . py را import کردیم، پایتون هیچ مشکلی برای import کردن b . py نداشت، چون b . py نیازی به مشخص بودن هیچ مقداری از a . py در هنگام import شدن ندارد. تنها اشاره ای که به a . py در b . py شده است در قسمت ( g است که در لحظه ای که a را import می کنیم درخواست نمی شود، پس مشکلی در این زمینه نخواهیم داشت. ولی اگر بخواهیم b . py را import کنیم (بدون آنکه ابتدا a . py را import کرده باشیم) ، به مشکل برخواهیم خورد. مشکل اینجاست که در پروسه import کردن b . py ، پایتون برای import کردن a . py نیز تلاش می کند. این اتفاق باعث درخواست شدن تابع ( f است که در نتیجه باعث درخواست شدن مقدار b . x است، ولی این مقدار تاکنون تعریف نشده است، پس به ارور AttributeError بر می خوریم. یک راه آسان برای حل کردن این مشکل این است که به جای اینکه در ابتدای b . py فایل a را import کنیم، درون تابع g ( سعی بر import کنیم، پس b . py بدین شکل خواهد بود: که باعث می شود خروجی ما بعد از درخواست کردن b . g ( اینگونه باشد: که عدد اول توسط قسمت ( print f موجود در انتهای a . py (که در ( b . g فراخوانی شده است) چاپ شده است و عدد دوم توسط دستور ( print a . f در انتهای ( b . g چاپ شده است. یکی از ویژگی های برجسته پایتون، وسعت و عظمت کتابخانه هایی است که پایتون به طور پیش فرض شامل آنان است. ولی بر اثر این وسعت، احتمال این وجود دارد که نام یک ماژول نوشته شده توسط برنامه نویس با یکی از ماژول های کتاب خانه ی استاندارد پایتون یکسان باشد (برای مثال ممکن است برنامه نویس یک ماژول برای دسترسی به ایمیل نوشته باشد که نام آن را email . py گذاشته باشد، این نام با نام یکی از ماژول های موجود در کتاب خانه ی پیش فرض پایتون یکسان است و باعث مشکل خواهد شد) این اشتباه می تواند به مشکلات بسیار پیچیده ای منجر شود. پایتون نه تنها در هنگام استفاده از ماژول نوشته شده توسط برنامه نویس به مشکل خواهد خورد، بلکه ممکن است یک ماژول نامرتبط نیاز به استفاده از ماژولی در کتاب خانه ی استاندارد پایتون داشته باشد که هم نام ماژول دست ساز ماست. این اشتباه در نام گذاری ماژول باعث می شود که آن ماژول نامرتبط، ماژول اشتباه را برای کار خودش استفاده کند که منجر به ارور و کار نکردن برنامه می شود. به همین علت، در هنگام نام گذاری باید حداکثر دقت را به کار برد که از اینگونه نام های موجود در کتاب خانه های استاندارد پایتون استفاده نشود. عوض کردن نام یک ماژول دست نویس توسط خودتان در برنامه خودتان بسیار راحت تر از پرکردن و ارسال یک درخواست تغییر نام ماژول پیش فرض پایتون (در یک فرم Python Enhancement Proposal یا PEP ) خواهد بود. کد زیر ( foo . py ) را در نظر داشته باشید: این کد در پایتون بدون هیچ مشکلی اجرا خواهد شد: ولی اگر همین برنامه را در پایتون اجرا کنیم به مشکل برخواهیم خورد: چه شد؟ چرا به مشکل برخوردیم؟ مشکل این است که در پایتون ، جسم exception خارج از حدود قسمت except در کد قابل دسترسی نخواهد بود. یک راه برای حل این مشکل این است که یک اشاره خارج از قسمت except در کد به جسم exception داشته باشیم تا بتوان به آن دسترسی داشت. کد زیر از این روش استفاده می کند و به این علت با پایتون و قابل اجراست و خروجی مورد نظر ما را خواهد داشت: اگر این کد را در پایتون اجرا کنیم می بینیم که بدون مشکلی اجرا خواهد شد: اشتباه استفاده اشتباه از سطح این اشتباه کمی بالاتر از اشتباهات قبلیست. اگر کد زیر را در فایلی به نام mod . py داشته باشیم: و بخواهیم از یک کد دیگر مثل کد زیر به آن دسترسی پیدا کنیم: می بینیم که به ارور AttributeError بر می خوریم. چرا؟ مشکل این است که وقتی کار مفسر زبان پایتون به اتمام می رسد و خاموش می شود، مقدار متغیرهای عمومی ماژول ما برابر با None خواهد شد. در نتیجه این رفتار، وقتی به مرحله ای میرسیم که دستور اجرا می شود، مقدار متغیر foo قبلا برابر None شده است. یکی از راه حل های موجود برای این مشکل می تواند استفاده از باشد. با استفاده از این دستور، وقتی اجرای برنامه شما به اتمام می رسد، هندلرهای برنامه قبل از خاموش شدن مفسر از بین می روند. برای اجرای این راه حل، شکل کد ما اینگونه خواهد بود: این روش استفاده از این دستور، راه مناسب و قابل اعتمادی برای اجرای پاکسازی های موردنیاز در هنگام اتمام اجرای برنامه است. در این پست دو قسمتی سعی شده به برخی از اشتباهاتی که ممکن است در هنگام استفاده از پایتون توسط برنامه نویسان انجام شود بپردازیم. امیدواریم که این نوشته مفید باشه براتون. امیر هستم از ایران پایتونیرز، ممنونم از وقتی که برای خوندن قسمت دوم این پست گذاشتید. ما به تازگی استفاده از پلتفرم ویرگول رو شروع کردیم و به زودی مطالب بیشتری هم اینجا قرار داده میشه. برای دیدن ویدیو های آموزشی دیگری که دوستانم برای شما ساخته اند، می تونید به کانال ما در، یا مراجعه کنید. منبع: