Of course! The python sched module is a powerful tool for scheduling tasks to run at specific times or after a certain delay. It's an in-process scheduler, meaning it runs entirely within your single Python program and is not suitable for system-wide tasks like cron jobs.

Let's break down how to use it, starting with the core concepts and moving to practical examples.
Core Concepts of the sched Module
The scheduler class has three main components you'll work with:
-
scheduler(timefunc, delayfunc): The constructor.timefunc: A function that returns the current time in seconds (as a float). The default istime.time, which is perfect for most cases.delayfunc: A function that pauses the execution of the program for a specified number of seconds. The default istime.sleep, which is also perfect for most cases.
-
scheduler.enter(delay, priority, action, argument=(), kwargs={}): This is the heart of the module. It schedules an event to be put into the queue.
(图片来源网络,侵删)delay: The time in seconds to wait before running the action.priority: An integer. If two events are scheduled for the same time, the one with the lower priority number will run first. You can often just use0or1.action: The function to be called when the event is run.argument: A tuple of positional arguments to pass to theactionfunction.kwargs: A dictionary of keyword arguments to pass to theactionfunction.
-
scheduler.run(blocking=True): This starts the scheduler. It processes the events in the queue in chronological order (and by priority for ties).blocking=True(the default): Therun()method will block execution until all scheduled events have been processed. This is the most common way to use it.blocking=False: Therun()method will process only the next event that is due and then return immediately. This is useful for integrating the scheduler into a larger, non-blocking application (like one using a GUI framework or an async server).
Example 1: Basic Scheduling with a Delay
This is the simplest use case: scheduling a function to run after a certain number of seconds.
import sched
import time
def my_task(name):
"""A simple task to be scheduled."""
print(f"Hello, {name}! The current time is: {time.strftime('%H:%M:%S')}")
# Create a scheduler instance
# We use the defaults for time and delay functions
s = sched.scheduler(time.time, time.sleep)
# Schedule 'my_task' to run in 5 seconds.
# Arguments for my_task are passed as a tuple: ('World',)
s.enter(5, 1, my_task, argument=('World',))
print(f"Scheduling task to run in 5 seconds. Current time: {time.strftime('%H:%M:%S')}")
# Start the scheduler. This will block until all events are done.
s.run()
print("Scheduler has finished.")
Output:
Scheduling task to run in 5 seconds. Current time: 10:30:00
# (5 seconds of pause here)
Hello, World! The current time is: 10:30:05
Scheduler has finished.
Example 2: Scheduling a Task for a Specific Time
You can also schedule a task to run at a specific wall-clock time.

import sched
import time
def water_the_plants():
"""A task that needs to run at a specific time."""
print("Time to water the plants! It's 15:00 sharp.")
# Create scheduler
s = sched.scheduler(time.time, time.sleep)
# Calculate the delay until 15:00 (3 PM)
# Get current time in seconds since epoch
current_time = time.time()
# Target time is 15:00 (3 PM)
target_hour = 15
target_minute = 0
target_second = 0
# Get today's date and construct the target time in seconds
target_time_struct = time.localtime(current_time)
target_time_struct = target_time_struct[:3] + (target_hour, target_minute, target_second) + target_time_struct[6:]
target_time = time.mktime(target_time_struct)
# If the target time for today has already passed, schedule it for tomorrow
if target_time < current_time:
target_time += 24 * 60 * 60 # Add one day in seconds
delay = target_time - current_time
print(f"Current time: {time.strftime('%H:%M:%S')}")
print(f"Scheduling 'water_the_plants' to run at 15:00. Delay is {delay:.2f} seconds.")
# Schedule the task
s.enter(delay, 1, water_the_plants)
# Run the scheduler. It will wait until the calculated delay is over.
s.run()
print("Scheduler finished.")
Output (if run before 3 PM):
Current time: 14:30:00
Scheduling 'water_the_plants' to run at 15:00. Delay is 1800.00 seconds.
# (30 minutes of pause here)
Time to water the plants! It's 15:00 sharp.
Scheduler finished.
Example 3: Scheduling Recurring Tasks
This is where sched can get a bit tricky. The run() method is blocking, so it won't return until all events are done. To create a recurring task, you need to have the task itself re-schedule itself when it runs.
The key is to run the scheduler in a non-blocking way and manage the loop yourself.
import sched
import time
def recurring_task(scheduler, msg, interval):
"""A task that schedules itself to run again."""
print(f"{msg} - Time: {time.strftime('%H:%M:%S')}")
# Schedule the next run of this same task
scheduler.enter(interval, 1, recurring_task, (scheduler, msg, interval))
def main():
s = sched.scheduler(time.time, time.sleep)
message = "Running recurring task"
run_interval = 3 # Run every 3 seconds
# Schedule the first run
s.enter(run_interval, 1, recurring_task, (s, message, run_interval))
print("Starting scheduler for a recurring task every 3 seconds.")
print("It will run for 10 seconds and then stop.")
# We need our own loop to run the scheduler non-blockingly
end_time = time.time() + 10 # Run for 10 seconds
while time.time() < end_time:
# Run the scheduler to process the next event
# The `run(blocking=False)` will process only the next due event
# and then return control to our loop.
s.run(blocking=False)
# A small sleep to prevent the loop from consuming 100% CPU
time.sleep(0.1)
print("\nScheduler stopped after 10 seconds.")
if __name__ == "__main__":
main()
Output:
Starting scheduler for a recurring task every 3 seconds.
It will run for 10 seconds and then stop.
Running recurring task - Time: 10:35:00
Running recurring task - Time: 10:35:03
Running recurring task - Time: 10:35:06
Running recurring task - Time: 10:35:09
Scheduler stopped after 10 seconds.
Important Considerations and Caveats
-
Blocking Nature: The
s.run()method is blocking. This means it will freeze your main thread until all scheduled events are complete. For long-running or recurring tasks, you must use thes.run(blocking=False)pattern inside your own loop, as shown in Example 3. -
Not a Production Scheduler: For serious, production-level scheduling, you should consider more robust libraries:
APScheduler(Advanced Python Scheduler): The most popular choice. It supports multiple backends (memory, database, Redis), cron-like scheduling, and is designed for long-running applications.Celery: A distributed task queue. It's perfect for background jobs that need to run on multiple machines and be resilient to failures.asyncio: If you are building an asynchronous application,asyncio's own scheduling tools (likeloop.call_later) are a more natural fit.
-
Time Precision: The precision of your scheduled events depends on the underlying
time.sleep()function and the operating system's scheduler. For most applications, this is more than sufficient.
Summary: sched.enter vs. Other Methods
| Method | Description | When to Use |
|---|---|---|
enter(delay, ...) |
Schedules an event to run after a specific delay (in seconds). |
The most common method. Use it for one-off delayed tasks or for calculating the delay until a specific wall-clock time. |
enterabs(time, ...) |
Schedules an event to run at a specific absolute time (in seconds since epoch). |
Very useful for scheduling tasks for a specific moment in time (e.g., "at midnight"). It can be more direct than calculating a delay. |
enterabs(time, ...) |
Cancels an event from the scheduler's queue. | Essential if you need to remove a scheduled task before it runs. You need the event returned by enter() or enterabs(). |
