اشتباهات رایج هنگام برخورد با پرونده‌های چندگانه پایتون

شکل ۱. پرونده‌های چندگانه پایتون
شکل ۱. پرونده‌های چندگانه پایتون
منتشر‌شده در وبسایت towardsdatascience به تاریخ ۱۱ می ۲۰۲۱
لینک منبع: Common Mistakes When Dealing with Multiple Python Files

در ساده‌ترین حالت، ما کدها را در یک فایل پایتون می‌نویسیم (نام فایل با py. تمام می‌شود) ما آن را اداره می‌کنیم و همه چیز مطابق انتظار کار می‌کند، و خوشحال هستیم. با این حال، وقتی شما باید کدهای خود را به چند فایل پایتون تقسیم کنید، همه چیز می‌تواند کمی پیچیده شود، معمولا برای مدیریت آسان‌تر کد و خوانایی. در این مقاله، من قصد دارم چند اشتباه رایج که در آن‌ها گیر کرده‌ام را به شما نشان دهم و امیدوارم که شما هم مانند من اشتباه نکنید.

در پایتون، هر فایل پایتون در واقع یک اصطلاح خاص به نام «ماژول» دارد، و زمانی که شما از نحو معروف import استفاده می‌کنید، شما در حال ساختن اتصال بین چندین ماژول پیتون مختلف برای رسیدن به یک کار پیچیده در زمینه خودتان هستید. در اینجا، قصد دارم موضوعات زیر را به تصویر بکشم:

  1. هر فایل متغیر جهانی خاص خود را دارد.
  2. این تابع همیشه به یاد می‌آورد که در کجا ایجاد شده‌است
  3. پایتون «گذر از مرجع» است.
  4. استفاده از یک فایل جداگانه برای نگه داشتن متغیر GLOBAL در میان چندین فایل پایتون

اگر آن‌ها چیزی هستند که شما می‌خواهید کمی بیشتر در مورد آن‌ها بدانید، به خواندن ادامه دهید!

هر ماژول / فایل متغیر جهانی خاص خود را دارد

زمانی که شما یک متغیر (نه در یک تابع) را در یک فایل پایتون ایجاد می‌کنید، این متغیر را بر فضای نام ماژول فعلی سوار می‌کنید. هر فرمانی در این فایل پایتون می‌تواند به مقدار متغیر دسترسی داشته باشد، آن را بخواند و اصلاح کند، یعنی به یک متغیر جهانی تبدیل شود. شما همچنین می‌توانید با اعلام جهانی بودن آن، به صراحت یک متغیر را در عملکرد جهانی تعریف کنید.

شکل ۲. ایجاد یک متغیر محلی جهانی
شکل ۲. ایجاد یک متغیر محلی جهانی

با این حال، متغیرهای جهانی در فایل‌های مختلف پایتون به اشتراک گذاشته نمی‌شوند. برای نشان دادن این موضوع، بیایید به مثال زیر نگاه کنیم:

شکل ۳. متغیرهای جهانی برای هر ماژول منحصر به فرد هستند
شکل ۳. متغیرهای جهانی برای هر ماژول منحصر به فرد هستند

منطق بسیار روشن است، من یک تابع در sub_module.py تعریف کردم و سعی کردم آن را در فایل main.py فراخوانی کنم. به نظر می‌رسد که من متغیر num=5 را در فایل main.py تعریف کردم اما معلوم شد که این تابع نمی‌تواند به آن دسترسی داشته باشد، دلیل آن این است که sub_module.py نمی‌تواند به متغیر جهانی در دیگر ماژول‌های پایتون دسترسی داشته باشد، بنابراین num=5 برای این برنامه نامرئی است. چگونه آن را اصلاح کنیم؟ فقط num را در فایل درست تعریف کنید.

شکل ۴. یک متغیر را در زیر-پیمانه تعریف کنید
شکل ۴. یک متغیر را در زیر-پیمانه تعریف کنید
مطالعه مقاله آموزش تمام مدل‌های طبقه‌بندی یا رگرسیون در یک خط کد پایتون توصیه می‌شود.

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

من مطمئن نیستم که آیا شما هیچ گونه سردرگمی در مورد مثال بالا را تجربه کرده‌اید؟ من تجربه کردم وقتی برای اولین بار به این مثال نگاه کردم چون به صراحت test_func1 را از sub_module.py به main.py وارد کردم، طبیعی است که فکر کنم این عملکرد در حوزه فعلی بوده‌ است، اینطور نیست؟

اما تابع پایتون همیشه می‌داند که در کجا ایجاد شده است. اگرچه به نظر می‌رسد که test_func1 در main.py است، اما وقتی که اجرا می‌شود هنوز هم بهsub_module.py تعلق دارد زیرا این همان جایی است که ایجاد شده است. در اینجا به نکات عملی مفید دیگری اشاره می‌کنیم:

به یاد داشته باشید که بسته‌های لازم را نیز در زیرماژول وارد کنید!

شکل ۵. وارد کردن نومیپی در زیر ماژول را فراموش کنید
شکل ۵. وارد کردن نومیپی در زیر ماژول را فراموش کنید

در مثال بالا، از آنجایی که ما فراموش کردیم بسته نومپی را در sub_module.py وارد کنیم، حتی اگر آن را در main.py وارد کنیم، باز هم برای test_func1 قابل‌دسترسی نیست. حالا اجازه دهید آن را ثبت کنیم:

شکل ۶. وارد کردن بسته عددی در زیر ماژول
شکل ۶. وارد کردن بسته عددی در زیر ماژول

عبور از طریق ارجاع در مقابل عبور از مقدار

مثال اول جواب می‌دهد، اما عجیب به نظر می‌رسد، اینطور نیست؟ معمولا ما به جای قرار دادن یک متغیر منفردnum=5 فقط تابع و کلاس را در زیر ماژول تعریف می‌کنیم. روش معمول برای حل این مشکل اضافه کردن num به عنوان یک استدلال در test_func1 و همچنین عبور num = ۵ به تابع در هنگام فراخوانی آن در فایل main.py است.

شکل ۷. متغیر پاس به عنوان آرگومان
شکل ۷. متغیر پاس به عنوان آرگومان

حال سوال این است که چگونه می‌توان sub_module.py را تشخیص داد که num کجاست؟ این بدان دلیل است که پایتون همواره به جای عبور از مقدار، از مرجع عبور می‌کند. برای نشان دادن آن، بیایید نگاهی به آنچه که در واقع در زمان اجرای آن اتفاق می‌افتد، بیندازیم:

شکل ۸. عبور از طریق مرجع در مقابل عبور از طریق مقدار
شکل ۸. عبور از طریق مرجع در مقابل عبور از طریق مقدار

وقتی شما num=5 را در main.py تایپ می‌کنید، شما اساسا PyObject را با یک نوع عدد صحیح می‌سازید که در یک قطعه حافظه فیزیکی زندگی می‌کند، و شما از نام num برای اشاره به این قطعه حافظه فیزیکی استفاده می‌کنید. حالا که پایتون همیشه از مرجع عبور می‌کند، شما می‌توانید در نظر بگیرید کهtest_func1 خواهد فهمید num به کجا اشاره می‌کند. در نتیجه به value دسترسی خواهد داشت چون دقیقا می‌داند که اینvalue کجا قرار دارد.

آیا می‌توانم یک متغیر جهانی مشترک در میان فایل‌های مختلف داشته باشم؟

همانطور که بحث کردیم، متغیر جهانی منحصر به مدول خود است. اما گاهی اوقات ما واقعا می‌خواهیم یک متغیر GLOBAL داشته باشیم که قابل‌دسترسی باشد، که توسط هر فایل پایتون در دایرکتوری اصلاح شده باشد. روش کانونیکال برای رسیدن به این هدف، ایجاد یک فایل دیگر با متغیرهای GLOBAL شماست.

شکل ۹. یک فایل جداگانه برای نگهداری متغیر GLOBAL
شکل ۹. یک فایل جداگانه برای نگهداری متغیر GLOBAL
شاید مطالعه مقاله کد پایتون خود را با سرعتC اجرا کنید! برای شما مفید باشد.

من عمدا این مثال را کمی پیچیده کردم؛ در اینجا یک فایل پایتون gloabl_.py داریم که حاوی num=10 است. اما در فایل main.py، من num=5 را نیز ایجاد کردم. اگر چه هر دوی آن‌هاnum نامیده شدند، اما این تفاوت‌ها در حوزه متفاوتی قرار دارند. در main.py، ما این متغیر GLOBAL را با اضافه کردن ۱ اصلاح می‌کنیم و این تغییر درsub_module.py نیز منعکس خواهد شد. با توجه به اینکه در اینجا باید global_ را در تابع test_func2 وارد کنم، چون اگر نحو واردات را در ابتدا قرار دهم، num وارد شده قبل از اجرای خط global_.AHDG F82 + = ۱ خواهد بود. به یاد داشته باشید که sub_module.py در خط from sub_module import * اجرا شد، می‌توانیم آن را در مثال زیر آزمایش کنیم:

شکل ۱۰. ترتیب وارد کردن موضوعات نحوی بسیار مهم است
شکل ۱۰. ترتیب وارد کردن موضوعات نحوی بسیار مهم است

همانطور که دیدید، حالا حتی اگر متغیر جهانی num به اندازه ۱ افزایش داشته باشد، در sub_module.py منعکس نشده است زیرا متغیر وارداتی آن‌ها قبل از عملیات آمده است. در زمان وارد کردن، پایتون به طور خودکار یک کپی برای شما خواهد ساخت بنابراین global_.num قدیمی و global_.num جدید در حافظه فیزیکی کاملا متفاوتی زندگی می‌کنند.

نتیجه‌گیری

در اینجا برخی از بهترین روش‌ها برای موقع سروکار داشتن با فایل‌های مختلف پایتون آورده شده است:

  1. متغیر را به عنوان آرگومان رد کنید، زیرا پایتون «عبور از طریق مرجع»، که تضمین می‌کند که زیر ماژول شما می‌تواند به متغیری که شما رد کردید، دسترسی داشته باشد.
  2. فراموش نکنید که بسته مورد نیاز را نیز در ماژول فرعی وارد کنید، زیرا این تابع همیشه به یاد می‌آورد که در کجا ایجاد شده است.
  3. استفاده از یک فایل جداگانه برای نگه داشتن متغیر GLOBAL در ماژول‌های پایتون اما در نظر داشته باشید که وارد کردن متغیر GLOBAL یک کپی از متغیر اصلی را می‌سازد بنابراین همیشه بررسی کنید که آیا شما به متغیر درست در برنامه تان اشاره می‌کنید یا خیر.

موضوع این است! امیدوارم این مقاله برای شما جالب و مفید باشد، ممنون از مطالعه شما!

این متن با استفاده از ربات مترجم مقالات علم داده ترجمه شده و به صورت محدود مورد بازبینی انسانی قرار گرفته است.در نتیجه می‌تواند دارای برخی اشکالات ترجمه باشد.
مقالات لینک‌شده در این متن می‌توانند به صورت رایگان با استفاده از مقاله‌خوان ترجمیار به فارسی مطالعه شوند.