آموزش

تابع ()time.sleep در پایتون

در این آموزش، با نحوه عملکرد تابع ()time.sleep آشنا می‌شی و یاد می‌گیری چطور ازش در برنامه‌هات استفاده کنی.

تاریخ انتشار:
31 مرداد 1405
پایتون
7 دقیقه
کاربرهای فینکا در چه شرکت‌هایی مشغول به کار هستند؟

در این آموزش، با تابع sleep() در پایتون آشنا می‌شی که بهت اجازه می‌ده در اجرای برنامه‌ت تاخیر ایجاد کنی. این تابع خیلی به درد می‌خوره، مخصوصاً وقتی برنامه‌ت با threadها کار می‌کنه یا حتی وقتی با گرافیک و انیمیشن سروکار داری. تابع sleep در ماژول time قرار داره که کلی تابع برای دسترسی به زمان و تبدیلشون داره. با اینکه این ماژول در همه سیستم‌عامل‌ها وجود داره، ولی ممکنه همه توابعش در دسترس نباشن یا دقیقاً یه جور کار نکنن. بیا تابع time.sleep() رو دقیق‌تر بررسی کنیم.

ماژول time

این ماژول توابعی داره که کمک می‌کنن زمان رو مدیریت کنی و در برنامه‌ت ازشون استفاده کنی. ماژول‌های دیگه‌ای هم هستن که دقیق‌تر با تاریخ و تقویم سیستم کار می‌کنن، اما تمرکز ماژول time بیشتر روی مدیریت زمانه؛ از کار با ساعت‌ها گرفته تا میلی‌ثانیه‌ها.

یکی از اصطلاحاتی که در دنیای کامپیوتر موقع کار با زمان زیاد می‌شنوی، ایپاک (epoch) هست.

اما اول از همه، مطمئن شو که ماژول time رو وارد کردی. برای این کار کافیه بنویسی:

ایپاک

این دقیقاً همون نقطه‌ایه که زمان واقعاً در سیستم شروع شده. منظورمون تولد منظومه شمسی یا زمانی که انسان شروع به اندازه‌گیری زمان کرد نیست، بلکه به زمان حال خیلی نزدیک‌تره. در سیستم‌های یونیکس، مبدأ زمان یا همون ایپاک برابره با ۱ ژانویه ۱۹۷۰ ساعت 00:00:00 (به زمان UTC) که روز پنجشنبه بوده. برای پیدا کردن ایپاک در سیستم خودت می‌تونی این کد رو بنویسی:

این کد بهت سال (tm_year)، ماه (tm_mon)، روز (tm_mday)، ساعت (tm_hour)، دقیقه (tm_min) و ثانیه (tm_sec) رو می‌ده. در کنارش، روز هفته (tm_wday) رو هم داریم

که مقدار ۳ می‌شه چون دوشنبه شروع هفته حساب می‌شه و مقدارش صفره. بعد از اون، روزِ سال (tm_yday) یا همون روز ژولین میاد. و در نهایت فلگ ساعت تابستانی (tm_isdst).

کلمه DST مخفف daylight saving time یا همون ساعت تابستانیه. این فیلد می‌تونه مقادیر 0، 1- یا 1 رو بگیره. مقدار 0 یعنی ساعت تابستانی اعمال نمی‌شه. مقدار 1 یعنی ساعت تابستانی فعاله و در نهایت 1- یعنی این اطلاعات در دسترس نیست. شاید بپرسی چرا در دسترس نیست؟ چون قوانین DST رو هر کشوری خودش تعیین می‌کنه و ممکنه تغییر کنن.

بیشتر کامپیوترها زمان و تاریخ رو به صورت اختلاف ثانیه‌ها از تاریخ ۱ ژانویه ۱۹۷۰ ساعت 00:00:00 (به زمان UTC) تا همون لحظه نگه می‌دارن. پس اگه تایپ کنی:

این کد تعداد ثانیه‌هایی که از ۱ ژانویه ۱۹۷۰ ساعت 00:00:00 (به زمان UTC) گذشته رو نشون می‌ده. این اختلاف همون چیزیه که بهش timestamp یا زمان یونیکس ایپاک (UNIX epoch) می‌گن و به شکل یه عدد اعشاری نمایش داده می‌شه. البته این اختلاف در واقع بر حسب ثانیه نیست، بلکه با چیزی به اسم تیک‌ (tick) سنجیده می‌شه. در بیشتر سیستم‌های یونیکس، ساعت بین ۵۰ تا ۱۰۰ بار در ثانیه «تیک» می‌زنه. پس زمان یونیکس ایپاک در واقع تعداد تیک‌هایی هست که از ۱ ژانویه ۱۹۷۰ ساعت 00:00:00 (به زمان UTC) رخ داده.

حالا که فهمیدی ماژول time دقیقاً چیکار می‌کنه، بیا یه نگاهی به تابع sleep() بندازیم.

()time.sleep

به زبون ساده، time.sleep() تعداد ثانیه‌هایی که می‌خوای برنامه‌ت متوقف بشه یا قبل از رفتن به مرحله بعد در حالت تعلیق بمونه رو به عنوان آرگومان می‌گیره. بیا این تابع رو در یه برنامه ساده ببینیم؛ برنامه‌ای که فقط زمان فعلی رو با یه توقف ۵ ثانیه‌ای چاپ می‌کنه. یعنی بین هر بار چاپ زمان فعلی، ۵ ثانیه فاصله می‌افته. استفاده از time.ctime() هم کمک می‌کنه تا زمان محلی رو خیلی مرتب‌تر ببینی.

خروجی
Sun Jan 27 18:46:24 2019
Sun Jan 27 18:46:29 2019
Sun Jan 27 18:46:34 2019
Sun Jan 27 18:46:39 2019
Sun Jan 27 18:46:44 2019

نحوه نوشتن این تابع به این صورته: time.sleep(sec) که در اون sec همون آرگومانیه که مشخص می‌کنه برنامه چند ثانیه باید متوقف بشه. این تابع هیچ مقداری رو برنمی‌گردونه.

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

خروجی
Sun Jan 27 18:46:49 2019
Sun Jan 27 18:46:52 2019
Sun Jan 27 18:46:54 2019

پایتون هیچ تضمینی در مورد رفتار این تابع، مخصوصاً در سیستم‌عامل‌های مختلف نمی‌ده. دلیل اصلیش اینه که بیشتر توابع این ماژول، در واقع نسخه هم‌نام خودشون در کتابخانه C سیستم‌عامل رو صدا می‌زنن. دقتش هم واقعاً به دقت توقف (sleep) در سیستم‌عامل پایه بستگی داره و اگه می‌خوای بیشتر بدونی، بهتره مستندات سیستم‌عاملت رو بخونی، چون معنی این توابع در سیستم‌عامل‌های مختلف فرق می‌کنه.

با این حال، یه خبر خوب هم داریم: از پایتون ۳.۵ به بعد، time.sleep(secs) حداقل به اندازه secs (همون آرگومانی که بهش دادی) متوقف می‌مونه، حتی اگه با یه سیگنال قطع بشه (همون‌طور که بالاتر گفتیم، سیگنال رو همون فروشنده در نظر بگیر)؛ مگر اینکه مدیریت‌کننده سیگنال، خطایی ایجاد کنه.

پس وقتی از time.sleep() استفاده می‌کنیم در پس‌زمینه چه اتفاقی می‌افته؟
این بخش فقط برای اینه که تابع رو بهتر درک کنی و برای شروع کار باهاش، نیازی نیست اینا رو بدونی. این تابع در واقع از ساعت سیستم (System Clock) استفاده می‌کنه؛ یه قطعه الکترونیکی در کامپیوتر که یه سیگنال پایدار و با فرکانس بالا می‌فرسته تا همه قطعات داخلی رو با هم هماهنگ کنه و بخشی از پردازنده‌ست. این ماژول چیزی به اسم درخواست‌های وقفه (IRQs) رو در فاصله‌های زمانی قابل برنامه‌ریزی ایجاد می‌کنه. وظیفه درخواست‌های وقفه اینه که کدی که پردازنده داره اجرا می‌کنه رو متوقف کنن، وضعیت فعلی رو ذخیره کنن و بعدش کنترل رو به یه بخش دیگه از کد در سیستم‌عامل بسپارن.
پس کاری که تابع sleep() انجام می‌ده اینه که روتین تکمیل I/O در سطح پایین یا فراخوانی ناهمگام (asynchronous) رو صدا می‌زنه تا پردازش رو مسدود (block) کنه. سیستم‌عامل می‌فهمه که تا رسیدن به زمان تعیین‌شده (timeout) نمی‌خوای هیچ کار دیگه‌ای انجام بدی. وقتی این زمان تموم شد، سیستم‌عامل پردازش تو رو از آخرین وضعیتی که یادشه ادامه می‌ده. و از دید تو، فقط یه فراخوانی ساده به تابع time.sleep() انجام شده.

تبریک می‌گیم که به تابع time.sleep() مسلط شدی! حتماً به دوره مقدمه‌ای بر تابع‌ها در پایتون در فینکا سر بزن تا چیزای بیشتری درباره توابع پایتون یاد بگیری.

اشتراک‌گذاری
فهرست مطالب
  • ماژول time
  • ()time.sleep

دریافت اپلیکیشن فینکا

با اپلیکیشن فینکا، به بیشتر دوره‌ها و مسیرها روی موبایل دسترسی دارید، تمرین می‌کنید و یادگیری رو هم‌زمان روی موبایل و دسکتاپ ادامه می‌دید.