در بسیاری از پروژههای پایتونی، کار کردن با فایلها و پوشهها یکی از مهمترین بخشهای برنامهنویسی محسوب میشود. اینکه بتوانیم مسیرها را مدیریت کنیم، پوشه بسازیم، فایلها را بررسی کنیم یا حتی دستورات سیستمعامل را مستقیماً از داخل پایتون اجرا کنیم، به ما کمک میکند برنامههای کاربردیتر و حرفهایتری توسعه دهیم. پایتون برای انجام این کارها ابزارها و ماژولهای قدرتمندی در اختیار ما قرار داده است. یکی از مهمترین آنها ماژول os است که امکان تعامل مستقیم با سیستمعامل را فراهم میکند.
در این قسمت از دوره آموزشهای فنی و کاربردی کامپیوتر با پایتون، با مهمترین قابلیتهای این ماژول آشنا میشویم و یاد میگیریم چگونه:
- مسیر فعلی را دریافت کنیم
- بین دایرکتوریها جابهجا شویم
- پوشه ایجاد یا حذف کنیم
- فایلها و پوشهها را لیست کنیم
- و برخی دستورات خط فرمان را مستقیماً در پایتون اجرا کنیم
این مفاهیم پایهای، در ادامه مسیر برای مدیریت فایلها، اتوماسیون کارها و توسعه پروژههای حرفهای بسیار کاربردی خواهند بود.
ماژول OS در پایتون
دوستان، در این جلسه میخواهیم یاد بگیریم که چگونه کارهایی را که در جلسه قبل در محیط CMD انجام دادیم، این بار به کمک دستورات پایتون اجرا کنیم.
برای اجرای این دستورات، از محیط Shell خود پایتون استفاده میکنم.
در این دایرکتوری، روی نوار آدرس کلیک میکنم و CMD را باز میکنم. با این کار، پنجره CMD دقیقاً در همین مسیر اجرا میشود. سپس پایتون را اجرا میکنم تا وارد محیط Shell پایتون شوم.
اگر بخواهم محتوای اضافی صفحه را پاک کنم و محیط تمیزتری داشته باشم، میتوانم از دستور clear استفاده کنم.
برای اینکه بتوانیم دستورات سیستمعامل را با استفاده از پایتون اجرا کنیم، یک ماژول داخلی در پایتون به نام os داریم که مخفف عبارت Operating System است.
این ماژول را با دستور زیر ایمپورت میکنیم:
import osیکی از اولین کارهایی که میتوانیم با این ماژول انجام دهیم، دریافت مسیر دایرکتوری فعلی است؛ یعنی مسیری که اکنون در آن قرار داریم.
برای این کار، از تابع ()getcwd استفاده میکنیم:
os.getcwd()این تابع، مسیر دایرکتوری فعلی را با همین ساختار به ما نمایش میدهد و مشخص میکند که در حال حاضر در چه مسیری قرار داریم.

بعد از این، میتوانیم در همین دایرکتوری یک پوشه جدید ایجاد کنیم. برای انجام این کار، از تابع ()mkdir در ماژول os استفاده میکنیم:
os.mkdir("my_folder")در اینجا، نام پوشه را بهعنوان آرگومان به تابع پاس میدهیم. برای مثال، با اجرای این دستور یک پوشه با نام my_folder ساخته میشود.

حالا اگر بخواهیم بررسی کنیم که این پوشه ساخته شده است یا نه و همچنین محتویات دایرکتوری فعلی را مشاهده کنیم، میتوانیم از تابع ()listdir استفاده کنیم:
os.listdir()این تابع، اسامی تمام فایلها و پوشههای موجود در دایرکتوری فعلی را در قالب یک لیست برمیگرداند. در واقع، هر آیتم این لیست نشاندهنده یکی از موارد موجود در این مسیر است.

حالا فرض کنید میخواهیم وارد این پوشه شویم؛ دقیقاً مشابه دستور cd که در Command Prompt استفاده میکردیم.
برای این کار، از تابع ()chdir استفاده میکنیم:
os.chdir("my_folder")در این حالت، ما بهصورت نسبی آدرسدهی کردهایم.
آدرسدهی مطلق و نسبی
آدرسدهی نسبی یعنی مسیر را نسبت به دایرکتوری فعلی مشخص کنیم. به این معنا که پایتون فرض میکند از مسیر فعلی باید یک مرحله جلو برود و وارد پوشه my_folder شود. آدرسی که اینجا مشاهده میکنید، یک آدرس مطلق (Absolute Path) است.

یعنی مسیر بهصورت کامل و از ریشه مشخص شده است؛ برای مثال از درایو C شروع میشود و مرحلهبهمرحله تا دایرکتوری موردنظر ادامه پیدا میکند.
اما زمانی که ما فقط نام یک پوشه را وارد میکنیم، در واقع از آدرسدهی نسبی (Relative Path) استفاده کردهایم. در این حالت، مسیر نسبت به دایرکتوری فعلی در نظر گرفته میشود. برای مثال، وقتی در دایرکتوری فعلی دستور زیر را اجرا میکنیم:
os.chdir("my_folder")پایتون فرض میکند که باید یک مرحله جلو برود و وارد پوشه my_folder شود. اگر دوباره مسیر فعلی را بررسی کنیم:
os.getcwd()میبینیم که آدرس تغییر کرده و اکنون داخل پوشه my_folder قرار داریم.
بازگشت به دایرکتوری قبلی
اگر بخواهیم از دایرکتوری فعلی یک مرحله به عقب برگردیم، میتوانیم دوباره از ()chdir استفاده کنیم؛ اما این بار مقدار .. را به آن بدهیم:
os.chdir("..")دو نقطه .. به این معناست که یک مرحله به دایرکتوری قبلی بازگردیم. حالا اگر دوباره مسیر فعلی را بررسی کنیم:
os.getcwd()مشاهده میکنیم که از پوشه my_folder یک مرحله عقبتر آمدهایم.

اجرای دستورات خط فرمان در پایتون
تابع ()system
ماژول os یک تابع کاربردی دیگر به نام ()system نیز دارد.
این تابع به ما کمک میکند که دستورات خط فرمان را مستقیماً داخل پایتون اجرا کنیم.
برای مثال، اگر به خاطر داشته باشید در جلسه قبل از دستور dir برای نمایش فایلها و پوشههای موجود در یک دایرکتوری استفاده میکردیم. حالا میتوانیم همان دستور را در پایتون به این شکل اجرا کنیم:
os.system("dir")با اجرای این دستور، دقیقاً همان خروجی CMD را مشاهده میکنیم و لیست فایلها و پوشههای موجود نمایش داده میشود.

تابع ()walk
یکی دیگر از توابع جالب ماژول os، تابع ()walk است.
این تابع به ما کمک میکند که تمام فایلها و پوشههای موجود در یک دایرکتوری را بهصورت سلسلهمراتبی پیمایش و لیست کنیم؛ یعنی بتوانیم ساختار پوشهها و فایلها را از بالا به پایین یا برعکس بررسی کنیم.
برای استفاده از تابع ()walk باید مسیر دایرکتوری موردنظر را بهعنوان آرگومان به آن بدهیم؛ یعنی مشخص کنیم که میخواهیم محتویات کدام مسیر پیمایش و لیست شود. از آنجایی که میخواهیم دایرکتوری فعلی بررسی شود، از . استفاده میکنیم:
os.walk(".")نقطه. به این معناست که دقیقاً دایرکتوری فعلی یا همان ریشهای که اکنون در آن قرار داریم، مبنای پیمایش باشد.
زمانی که این دستور را اجرا میکنیم، خروجی آن یک Generator است. فعلاً وارد جزئیات Generator نمیشویم، اما میتوانیم آن را داخل یک حلقه for استفاده کنیم. برای مثال:
for i in os.walk(".")
print(i)
در اینجا، هر مقداری که توسط ()walk تولید میشود، با دستور print نمایش داده خواهد شد.

اگر خروجی را بررسی کنیم، متوجه میشویم که در هر مرحله یک تاپل (Tuple) به ما برگردانده میشود.
هر تاپل شامل سه بخش است:
- مسیر دایرکتوری فعلی
- لیست پوشههای موجود در آن مسیر
- لیست فایلهای موجود در آن مسیر
برای مثال، در اولین مرحله چون پیمایش از دایرکتوری ریشه فعلی آغاز شده، مقدار بخش اول . خواهد بود. سپس در بخش دوم، نام پوشههای موجود نمایش داده میشود؛ برای مثال پوشههایی مثل:
- 01
- 02
- 03
و در بخش سوم، فایلهای موجود در همان مسیر نمایش داده میشوند؛ مثلاً ممکن است فقط یک فایل متنی با پسوند txt. وجود داشته باشد.
تابع ()walk بهصورت مرحلهبهمرحله داخل پوشهها حرکت میکند.
برای مثال، در مرحله بعد وارد پوشه 01 میشود. در این پوشه ممکن است دیگر زیرپوشهای وجود نداشته باشد، اما تعدادی فایل قرار داشته باشد که لیست آنها به همراه پسوندشان نمایش داده میشود. بعد از اینکه تابع ()walk پوشه 01 را بررسی میکند، وارد پوشه 02 میشود و سپس پوشه 03 را پیمایش میکند.
برای مثال، داخل پوشه 03 ممکن است یک پوشه دیگر به نام my_folder وجود داشته باشد. تابع ()walk وارد این پوشه نیز میشود و محتویات آن را بررسی میکند.
زمانی که پیمایش یک شاخه کامل شود، تابع دوباره به مسیر قبلی بازمیگردد و سراغ شاخه بعدی میرود. برای مثال، بعد از اتمام بررسی مسیر 03، وارد پوشه test میشود و آن را نیز پیمایش میکند. در واقع، تابع ()walk بهصورت مرحلهبهمرحله روی شاخههای دایرکتوری حرکت میکند و تمام مسیرها را تا انتها بررسی میکند.
تابع ()walk یک پارامتر دیگر هم دارد که مشخص میکند پیمایش از بالا به پایین انجام شود یا برعکس. بهصورت پیشفرض، مقدار پارامتر topdown برابر True است؛ یعنی ابتدا پوشههای سطح بالاتر بررسی میشوند و سپس وارد زیرپوشهها میشود. اما اگر مقدار این پارامتر را False قرار دهیم، پیمایش از پایین به بالا انجام میشود:
for item in os.walk(".", topdown=False):
print(item)در این حالت، تابع ابتدا به انتهاییترین پوشهها میرود و آنها را بررسی میکند، سپس مرحلهبهمرحله به مسیرهای بالاتر بازمیگردد تا در نهایت به دایرکتوری ریشه برسد. یعنی دقیقاً برعکس حالتی که بهصورت پیشفرض انجام میشد.

تابع ()rmdir
حالا دوباره مسیر فعلی را بررسی میکنیم و وارد همان پوشه 03 میشویم. برای حذف یک دایرکتوری، میتوانیم از تابع ()rmdir در ماژول os استفاده کنیم.
os.rmdir("my_folder")در اینجا، نام پوشهای که میخواهیم حذف شود را بهعنوان آرگومان به تابع میدهیم. برای مثال، با اجرای دستور بالا پوش my_folder حذف میشود. اگر بعد از آن دوباره محتویات دایرکتوری را بررسی کنیم:
os.listdir()مشاهده میکنیم که دیگر پوشهای با نام my_folder وجود ندارد. همچنین اگر File Explorer را بررسی کنیم، میبینیم که آن پوشه از سیستم نیز حذف شده است.

جمعبندی
ماژول os قابلیتهای بسیار زیادی در اختیار ما قرار میدهد و امکانات متنوعی برای کار با سیستمعامل فراهم میکند.
اما مهمترین کارهایی که فعلاً به آنها نیاز داریم شامل موارد زیر هستند:
- حرکت بین دایرکتوریها
- ساخت پوشه
- حذف پوشه
- دریافت لیست فایلها و دایرکتوریها
- اجرای دستورات خط فرمان
- پیمایش ساختار پوشهها
در این قسمت تلاش کردیم مهمترین و پرکاربردترین بخشهای این ماژول را بررسی کنیم. در قسمت بعد، قصد داریم با یک ماژول دیگر آشنا شویم که در کنار ماژول os به ما کمک میکند مدیریت فایلها، مسیرها و دسترسیها را سادهتر و حرفهایتر انجام دهیم. پس در ادامه دوره همراه من باشید.
