【初心者向け】Pythonで処理を数秒遅らせる方法|time.sleepの使い方完全ガイド

python

プログラミングをしていると、こんな場面に出会うことがあります:

  • 「連続でメッセージを出力すると、早すぎて読めない」
  • 「APIに連続でリクエストを送ると、サーバーから拒否される」
  • 「ゲームやアニメーションで、自然なタイミングを作りたい」
  • 「ユーザーが操作を理解する時間を与えたい」

このようなとき、プログラムに「少し待つ」という指示を出すことで、より使いやすく、安全なプログラムを作ることができます。

この記事では、Pythonで処理を遅らせる基本的な方法から実用的な応用例まで、初心者の方にもわかりやすく解説します。

実際に動くコード例をたくさん用意したので、ぜひ試しながら読み進めてください!


スポンサーリンク
  1. 基本中の基本:time.sleep()の使い方
    1. time.sleep()とは?
    2. なぜimportが必要なの?
    3. 基本的な使用例
  2. 秒数の指定方法:整数・小数・計算式も使える
    1. 整数での指定
    2. 小数での指定
    3. 計算式や変数での指定
    4. 実用的な例:段階的に速くなるアニメーション
  3. ループと組み合わせた実用的な使い方
    1. for文での定期実行
    2. while文での無限ループ
    3. プログレスバーの実装
    4. ゲームの例:じゃんけんゲーム
  4. 時間に関する便利な関数・テクニック
    1. 経過時間の測定
    2. より精密な時間測定
    3. 現在時刻の表示
    4. ランダムな待機時間
  5. 注意点とよくある間違い
    1. 注意点1:sleepは完全にブロックする
    2. 注意点2:GUIアプリケーションでの使用
    3. 注意点3:非同期処理での使用
    4. 注意点4:精度の限界
  6. 実用的な応用例とケーススタディ
    1. 応用例1:APIの呼び出し制限対応
    2. 応用例2:ログ監視システム
    3. 応用例3:簡単なWebスクレイピング
    4. 応用例4:バックアップシステム
  7. よくある質問(FAQ)
    1. Q1:sleep()の最大値に制限はありますか?
    2. Q2:ミリ秒やマイクロ秒単位での精密制御は可能ですか?
    3. Q3:sleep中にプログラムを中断する方法は?
    4. Q4:複数の処理を同時に遅らせることは可能ですか?
    5. Q5:Webアプリケーションでsleep()を使っても大丈夫ですか?
    6. Q6:sleep()中にメモリ使用量は変わりますか?
  8. まとめ:time.sleep()をマスターして、より良いプログラムを作ろう
    1. 基本的な使い方
    2. 注意すべきポイント

基本中の基本:time.sleep()の使い方

time.sleep()とは?

time.sleep()は、Pythonの標準ライブラリに含まれる関数で、指定した秒数だけプログラムの実行を停止させます。

基本的な書き方:

import time

print("処理開始")
time.sleep(3)  # 3秒間待つ
print("3秒後に表示されます")

実行結果:

処理開始
(3秒間の待機)
3秒後に表示されます

なぜimportが必要なの?

timeは標準ライブラリですが、使用前にimport timeと書く必要があります。

これは、Pythonが必要な機能だけをメモリに読み込むためです。

import文の書き方:

import time  # timeモジュール全体をインポート

# または
from time import sleep  # sleep関数だけをインポート

2番目の方法を使った場合は、time.sleep()ではなくsleep()と書けます。

基本的な使用例

import time

print("カウントダウンを開始します")
print("3...")
time.sleep(1)
print("2...")
time.sleep(1)  
print("1...")
time.sleep(1)
print("開始!")

time.sleep(秒数)で簡単に処理を遅らせることができます。


秒数の指定方法:整数・小数・計算式も使える

整数での指定

最もシンプルな使い方です:

import time

time.sleep(1)   # 1秒待つ
time.sleep(5)   # 5秒待つ
time.sleep(60)  # 60秒(1分)待つ

小数での指定

より細かい時間制御が可能:

import time

time.sleep(0.5)    # 0.5秒(500ミリ秒)待つ
time.sleep(0.1)    # 0.1秒(100ミリ秒)待つ
time.sleep(0.01)   # 0.01秒(10ミリ秒)待つ

計算式や変数での指定

動的な時間制御:

import time

# 変数を使用
wait_time = 2.5
time.sleep(wait_time)

# 計算式を使用
time.sleep(1 + 0.5)  # 1.5秒待つ
time.sleep(60 * 2)   # 120秒(2分)待つ

# ユーザー入力を使用
seconds = float(input("何秒待ちますか?: "))
time.sleep(seconds)

実用的な例:段階的に速くなるアニメーション

import time

print("だんだん速くなるカウント:")
for i in range(1, 6):
    print(f"カウント: {i}")
    time.sleep(2 - (i * 0.3))  # 徐々に短くなる待機時間

柔軟な時間指定により、様々な用途に対応できます。


ループと組み合わせた実用的な使い方

for文での定期実行

一定間隔での繰り返し処理:

import time

print("5回、1秒間隔でメッセージを表示します")
for i in range(5):
    print(f"{i + 1}回目: こんにちは!")
    time.sleep(1)
print("完了しました")

while文での無限ループ

定期的な監視やデータ取得:

import time
import datetime

print("現在時刻を5秒ごとに表示します(Ctrl+Cで終了)")
try:
    while True:
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print(f"現在時刻: {current_time}")
        time.sleep(5)
except KeyboardInterrupt:
    print("\nプログラムを終了します")

プログレスバーの実装

視覚的な進捗表示:

import time

def show_progress(total_steps, step_duration=0.1):
    print("処理中: [", end="")
    for i in range(total_steps):
        print("■", end="", flush=True)
        time.sleep(step_duration)
    print("] 完了!")

# 使用例
show_progress(20, 0.2)  # 20ステップ、各0.2秒

ゲームの例:じゃんけんゲーム

import time
import random

def janken_game():
    choices = ["グー", "チョキ", "パー"]
    
    print("じゃんけんゲームを開始します!")
    time.sleep(1)
    
    print("じゃーん")
    time.sleep(1)
    print("けーん")  
    time.sleep(1)
    print("ポン!")
    
    computer_choice = random.choice(choices)
    user_choice = input("あなたの手は?(グー/チョキ/パー): ")
    
    print(f"あなた: {user_choice}")
    print(f"コンピュータ: {computer_choice}")
    
    # 結果判定のロジックはここに追加

janken_game()

ループとの組み合わせで、動的で魅力的なプログラムが作れます。


時間に関する便利な関数・テクニック

経過時間の測定

処理時間を計測:

import time

start_time = time.time()
print("重い処理を開始...")

# 何らかの処理(例:大きな数の計算)
total = 0
for i in range(1000000):
    total += i

time.sleep(2)  # 意図的な待機

end_time = time.time()
elapsed_time = end_time - start_time

print(f"処理完了!所要時間: {elapsed_time:.2f}秒")

より精密な時間測定

高精度な時間測定:

import time

start = time.perf_counter()

# 処理を実行
time.sleep(1.5)

end = time.perf_counter()
print(f"実際の待機時間: {end - start:.4f}秒")

現在時刻の表示

時刻情報と組み合わせ:

import time
import datetime

def timed_message(message, delay=1):
    current_time = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"[{current_time}] {message}")
    time.sleep(delay)

# 使用例
timed_message("プログラム開始", 2)
timed_message("データ処理中", 3)
timed_message("処理完了")

ランダムな待機時間

自然なタイミングの演出:

import time
import random

def random_delay(min_sec=1, max_sec=3):
    delay = random.uniform(min_sec, max_sec)
    print(f"{delay:.1f}秒待機します...")
    time.sleep(delay)

# 使用例
for i in range(3):
    print(f"メッセージ {i + 1}")
    random_delay(0.5, 2.0)

time.sleep()と他の時間関数を組み合わせることで、より高度な時間制御が可能です。


注意点とよくある間違い

注意点1:sleepは完全にブロックする

問題のあるコード例:

import time

print("長時間の処理を開始します...")
time.sleep(60)  # 60秒間、何もできない
print("処理完了")

# この間、ユーザーは何も操作できない

改善例:

import time

print("処理中... (Ctrl+Cで中止)")
try:
    for i in range(60):
        print(f"残り {60-i} 秒", end="\r")
        time.sleep(1)
except KeyboardInterrupt:
    print("\n処理が中止されました")

注意点2:GUIアプリケーションでの使用

Tkinterでの問題例:

import tkinter as tk
import time

def bad_function():
    # これはGUIを固まらせる
    time.sleep(5)
    label.config(text="5秒経過しました")

root = tk.Tk()
label = tk.Label(root, text="ボタンを押してください")
label.pack()

button = tk.Button(root, text="押す", command=bad_function)
button.pack()

root.mainloop()

改善例(afterメソッドを使用):

import tkinter as tk

def good_function():
    label.config(text="5秒後に更新されます...")
    # 5秒後にupdate_labelを呼び出す
    root.after(5000, update_label)

def update_label():
    label.config(text="更新されました!")

root = tk.Tk()
label = tk.Label(root, text="ボタンを押してください")
label.pack()

button = tk.Button(root, text="押す", command=good_function)
button.pack()

root.mainloop()

注意点3:非同期処理での使用

asyncioでの間違った使用例:

import asyncio
import time

async def bad_async_function():
    print("開始")
    time.sleep(2)  # これは他の非同期処理をブロックする
    print("終了")

# これは問題のあるコード
asyncio.run(bad_async_function())

正しい非同期での待機:

import asyncio

async def good_async_function():
    print("開始")
    await asyncio.sleep(2)  # 他の処理をブロックしない
    print("終了")

async def another_function():
    for i in range(3):
        print(f"別の処理 {i + 1}")
        await asyncio.sleep(0.5)

async def main():
    # 複数の処理を同時実行
    await asyncio.gather(
        good_async_function(),
        another_function()
    )

asyncio.run(main())

注意点4:精度の限界

非常に短い時間での注意点:

import time

# マイクロ秒レベルの精度は保証されない
start = time.perf_counter()
time.sleep(0.001)  # 1ミリ秒のつもり
end = time.perf_counter()

print(f"実際の待機時間: {(end - start) * 1000:.2f}ミリ秒")
# 結果は1ミリ秒より長くなることが多い

time.sleep()の特性を理解して、適切な場面で使用することが重要です。


実用的な応用例とケーススタディ

応用例1:APIの呼び出し制限対応

レート制限を考慮したAPI呼び出し:

import time
import requests

def call_api_with_delay(urls, delay=1):
    """複数のAPIを順次呼び出し(レート制限対応)"""
    results = []
    
    for i, url in enumerate(urls):
        print(f"API呼び出し {i + 1}/{len(urls)}: {url}")
        
        try:
            response = requests.get(url)
            results.append(response.json())
        except Exception as e:
            print(f"エラーが発生しました: {e}")
            results.append(None)
        
        # 最後以外は待機
        if i < len(urls) - 1:
            print(f"{delay}秒待機...")
            time.sleep(delay)
    
    return results

# 使用例(実際のAPIを使う場合)
# api_urls = [
#     "https://api.example.com/data1",
#     "https://api.example.com/data2", 
#     "https://api.example.com/data3"
# ]
# results = call_api_with_delay(api_urls, delay=2)

応用例2:ログ監視システム

リアルタイムログ監視:

import time
import os
from datetime import datetime

def monitor_log_file(file_path, check_interval=5):
    """ログファイルを定期的に監視"""
    if not os.path.exists(file_path):
        print(f"ファイルが見つかりません: {file_path}")
        return
    
    print(f"ログ監視開始: {file_path}")
    print(f"チェック間隔: {check_interval}秒")
    print("Ctrl+Cで終了")
    
    last_size = os.path.getsize(file_path)
    
    try:
        while True:
            current_size = os.path.getsize(file_path)
            
            if current_size != last_size:
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                print(f"[{timestamp}] ファイルが更新されました")
                last_size = current_size
            
            time.sleep(check_interval)
            
    except KeyboardInterrupt:
        print("\n監視を終了します")

# 使用例
# monitor_log_file("/path/to/logfile.log", 3)

応用例3:簡単なWebスクレイピング

サーバーに負荷をかけないスクレイピング:

import time
import requests
from bs4 import BeautifulSoup

def scrape_multiple_pages(base_url, page_count, delay=2):
    """複数ページを順次スクレイピング"""
    results = []
    
    for page in range(1, page_count + 1):
        url = f"{base_url}?page={page}"
        print(f"ページ {page} を取得中: {url}")
        
        try:
            response = requests.get(url)
            soup = BeautifulSoup(response.content, 'html.parser')
            
            # ここで必要なデータを抽出
            # title = soup.find('title').text
            # results.append(title)
            
            print(f"ページ {page} の取得完了")
            
        except Exception as e:
            print(f"エラー: {e}")
        
        # サーバーへの負荷を考慮して待機
        if page < page_count:
            print(f"{delay}秒待機中...")
            time.sleep(delay)
    
    return results

# 使用例
# results = scrape_multiple_pages("https://example.com/articles", 5, 3)

応用例4:バックアップシステム

定期的なファイルバックアップ:

import time
import shutil
import os
from datetime import datetime

def backup_files(source_dir, backup_dir, interval_hours=24):
    """定期的にファイルをバックアップ"""
    if not os.path.exists(source_dir):
        print(f"ソースディレクトリが見つかりません: {source_dir}")
        return
    
    os.makedirs(backup_dir, exist_ok=True)
    
    print(f"バックアップ開始")
    print(f"ソース: {source_dir}")
    print(f"バックアップ先: {backup_dir}")
    print(f"間隔: {interval_hours}時間")
    
    try:
        while True:
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            backup_name = f"backup_{timestamp}"
            backup_path = os.path.join(backup_dir, backup_name)
            
            print(f"バックアップ実行: {timestamp}")
            shutil.copytree(source_dir, backup_path)
            print("バックアップ完了")
            
            sleep_seconds = interval_hours * 3600
            print(f"次のバックアップまで {interval_hours} 時間待機...")
            time.sleep(sleep_seconds)
            
    except KeyboardInterrupt:
        print("\nバックアップシステムを終了します")

# 使用例
# backup_files("/important/data", "/backup/location", 6)

まとめ: 実際のアプリケーションでは、適切な待機時間が重要な役割を果たします。


よくある質問(FAQ)

Q1:sleep()の最大値に制限はありますか?

A1: 理論的には制限はありませんが、実用的な制限があります。

import time

# 非常に長い時間も指定可能
time.sleep(86400)  # 24時間 = 86400秒

# ただし、実際には以下の問題があります:
# - プログラムが長時間応答しなくなる
# - システムリソースの無駄遣い
# - 意図しない動作の原因となる

長時間の待機が必要な場合は、小さな間隔で分割するか、より適切な仕組み(スケジューラーなど)を使用してください。

Q2:ミリ秒やマイクロ秒単位での精密制御は可能ですか?

A2: ある程度は可能ですが、限界があります。

import time

# ミリ秒単位(ある程度精密)
time.sleep(0.001)  # 1ミリ秒

# マイクロ秒単位(精度は保証されない)
time.sleep(0.000001)  # 1マイクロ秒

# より精密な制御が必要な場合
start = time.perf_counter()
while time.perf_counter() - start < 0.001:
    pass  # ビジーウェイト(CPU使用率が高くなる)

高精度が必要な場合は、threading.Timerや専用ライブラリの使用を検討してください。

Q3:sleep中にプログラムを中断する方法は?

A3: 複数の方法があります。

import time
import signal
import sys

# 方法1: KeyboardInterrupt(Ctrl+C)
try:
    print("10秒間待機します(Ctrl+Cで中断)")
    time.sleep(10)
except KeyboardInterrupt:
    print("\n中断されました")

# 方法2: シグナルハンドラーを使用
def signal_handler(sig, frame):
    print("\nプログラムを終了します")
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

# 方法3: 分割された短い待機
def interruptible_sleep(total_seconds):
    for i in range(total_seconds):
        try:
            print(f"残り {total_seconds - i} 秒")
            time.sleep(1)
        except KeyboardInterrupt:
            print("\n中断されました")
            break

interruptible_sleep(10)

Q4:複数の処理を同時に遅らせることは可能ですか?

A4: 並行処理を使用すれば可能です。

import time
import threading

def delayed_task(name, delay):
    print(f"タスク {name} 開始")
    time.sleep(delay)
    print(f"タスク {name} 完了")

# 複数のタスクを同時実行
threads = []
for i in range(3):
    thread = threading.Thread(target=delayed_task, args=[f"T{i+1}", 2])
    thread.start()
    threads.append(thread)

# すべてのタスクの完了を待機
for thread in threads:
    thread.join()

print("すべてのタスクが完了しました")

Q5:Webアプリケーションでsleep()を使っても大丈夫ですか?

A5: 通常は避けるべきですが、適切に使用すれば問題ありません。

# ❌ 悪い例:リクエスト処理で長時間待機
def bad_api_endpoint():
    time.sleep(10)  # サーバーが10秒間ブロックされる
    return {"status": "ok"}

# ✅ 良い例:バックグラウンドタスクで使用
import threading

def background_task():
    while True:
        # バックグラウンドでの定期処理
        process_queue()
        time.sleep(30)  # 30秒間隔

# バックグラウンドで実行
thread = threading.Thread(target=background_task, daemon=True)
thread.start()

Q6:sleep()中にメモリ使用量は変わりますか?

A6: sleep()自体はメモリを消費しませんが、プログラム全体のメモリは保持されます。

import time
import psutil
import os

def check_memory_usage():
    process = psutil.Process(os.getpid())
    return process.memory_info().rss / 1024 / 1024  # MB

print(f"開始時メモリ: {check_memory_usage():.2f} MB")

# 大きなデータを作成
big_data = [i for i in range(1000000)]
print(f"データ作成後: {check_memory_usage():.2f} MB")

# sleep中もメモリは保持される
time.sleep(5)
print(f"sleep後: {check_memory_usage():.2f} MB")


まとめ:time.sleep()をマスターして、より良いプログラムを作ろう

Pythonで処理を遅らせるtime.sleep()は、シンプルながら非常に強力な機能です。

適切に使用することで、プログラムの品質と使いやすさを大幅に向上させることができます。

基本的な使い方

  • import timetime.sleep(秒数)で簡単に実装
  • 整数、小数、変数、計算式での柔軟な時間指定
  • ループとの組み合わせで動的な処理が可能

注意すべきポイント

  • 同期処理では完全にブロックされる
  • GUIアプリケーションでは専用メソッドを使用
  • 非同期処理ではasyncio.sleep()を使用
  • 非常に短い時間の精度は保証されない

コメント

タイトルとURLをコピーしました