# sleep(), 範例...

## sleep()

***

`sleep(secs)` 將執行中的 thread 暫停給定的秒數 `secs`。通常用於模擬延遲、建立暫停或間隔 requests。 `secs` 可以是 float 以指示更精確的睡眠時間。

{% hint style="info" %}
&#x20;**`sleep()` 函數會 blocks (阻塞) 程式碼的執行，這意味著在睡眠期間不會運行其他程式碼。**

這可能不適合程序需要響應使用者的輸入或其他即時事件的情況。 如果您需要 non-blocking 延遲功能，可能需要 threading 或 asyncio...。
{% endhint %}

{% hint style="info" %}
**`sleep()` 不適合在 GUI 應用程序中使用它，因為它會使 GUI 無響應。**

在這種情況下，請使用計時器事件或單獨的 threads 來處理計時。
{% endhint %}

{% hint style="info" %}
**在 Windows 8.1 及更高版本上，`sleep()` 使用高解析度計時器，提供 100 奈秒 (nanoseconds) 的解析度。**
{% endhint %}

### 範例

***

有時，API 在一定時間內可以發送的 requests 數量有限制。在這種情況下，您可能需要等待才能發出另一個請求，以避免達到速率限制。

{% code title="PYTHON" %}

```python
import requests
import time

for i in range(10):
    response = requests.get('http://example.com')
    print(response.status_code)

    time.sleep(1)  # Wait for 1 second before the next request
```

{% endcode %}

{% code title="PYTHON" %}

```python
import time

def my_func():
    print("Function executed")

while True:
    my_func()
    time.sleep(0.5)  # Wait for 1 seconds before running the function again
```

{% endcode %}

**執行結果：**

```TXT
Function executed
Function executed
Function executed
Function executed
...
```

## 範例 – 倒數計時器

***

{% code title="PYTHON" %}

```python
import time

def countdown(t):
    while t:
        mins, secs = divmod(t, 60)
        timer = '{:02d}:{:02d}'.format(mins, secs)
        print(timer, end="\r")
        time.sleep(1)
        t -= 1
    print('Countdown over!')

# start countdown of 10 seconds
countdown(20)

```

{% endcode %}

{% code title="PYTHON" %}

```python
import time

class Countdown:
    def __init__(self, hours=0, minutes=0, seconds=0):
        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds

    def convert_seconds(self):
        total_seconds = self.hours * 3600 + self.minutes * 60 + self.seconds
        return total_seconds

    def countdown(self):
        t = self.convert_seconds()
        while t:
            hours, remainder = divmod(t, 3600)       # Calculate hours
            minutes, seconds = divmod(remainder, 60) # Calculate other
            timer = '{:02d}:{:02d}:{:02d}'.format(hours, minutes, seconds)
            print(timer, end="\r")
            time.sleep(1)
            t -= 1
        print('Countdown over!')

# With only seconds
countdown_time = Countdown(seconds=90)
countdown_time.countdown()

# With only minutes and seconds
countdown_time = Countdown(minutes=2, seconds=30)
countdown_time.countdown()

# With hours, minutes and seconds
countdown_time = Countdown(hours=0, minutes=1, seconds=30)
countdown_time.countdown()
```

{% endcode %}

## 範例 – 測量函數的性能

***

{% code title="PYTHON" %}

```python
import time
import random

def test_algorithm(func, data):
    start_time = time.perf_counter()
    func(data)
    end_time = time.perf_counter()
    return end_time - start_time

def algorithm1(data):
    return sorted(data)

def algorithm2(data):
    return list(set(data))

data = [random.randint(0, 100000) for _ in range(100000)]

time1 = test_algorithm(algorithm1, data)
time2 = test_algorithm(algorithm2, data)

print(f'Algorithm 1 took: {time1:4f} s')
print(f'Algorithm 2 took: {time2:4f} s')
```

{% endcode %}

### 測量函數的性能 – Pythonic

***

{% code title="PYTHON" %}

```python
import time
import random
from functools import wraps

def timer_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        print(f'{func.__name__} took: {end_time - start_time:4f} s')
        return result
    return wrapper

@timer_decorator
def algorithm1(data):
    return sorted(data)

@timer_decorator
def algorithm2(data):
    return list(set(data))

data = [random.randint(0, 100000) for _ in range(100000)]

algorithm1(data)
algorithm2(data)

```

{% endcode %}

### 測量函數的性能 – 遞迴 ver.

***

`_is_recursive_call` 預設為 `False`，因此對於頂層調用 (直接進行的調用)，將設置開始和結束時間並打印執行時間。 對於遞迴調用，`_is_recursive_call=True`，因此不會設置開始和結束時間，也不會打印執行時間。

{% code title="PYTHON" %}

```python
import functools
import random
import time

def measure_execution_time(func):
    '''
    _is_recursive_call is False by default, so for the top-level call (the one you make directly), 
    the start and end times will be set and the execution time will be printed. 
    For the recursive calls, _is_recursive_call=True, 
    so the start and end times won't be set and the execution time won't be printed.
    '''
    @functools.wraps(func)
    def wrapper(*args, _is_recursive_call=False, **kwargs):
        if not _is_recursive_call:
            wrapper._start_time = time.perf_counter()  # Set the start time only for the top-level call

        result = func(*args, **kwargs)  # Call the function

        if not _is_recursive_call:           # If this is the top-level call
            wrapper._end_time = time.perf_counter()  # Set the end time
            print(f"{func.__name__} executed in {wrapper._end_time - wrapper._start_time:.3f} s.")

        return result
    return wrapper 
    
@measure_execution_time
def fibonacci(n):  # Fibonacci sequence
    if n < 2:
        return n
    return fibonacci(n-1, _is_recursive_call=True) + fibonacci(n-2, _is_recursive_call=True)	

@measure_execution_time
def algorithm1(data):
    return sorted(data)

@measure_execution_time
def algorithm2(data):
    return list(set(data))

data = [random.randint(0, 100000) for _ in range(100000)]

algorithm1(data)
algorithm2(data)

fibonacci(20)
```

{% endcode %}

## 範例 – debugging

***

詳見: [functools【可調用物件】](/tech/python-library/functools-han-shu-gao-ji-cao-zuo.md)

{% code title="PYTHON" %}

```python
import functools
import random
import time

# Define debugging decorator
def debug(func):
    """Prints the function signature and return value"""
    @functools.wraps(func)
    def wrapper_debug(*args, **kwargs):
        args_repr = [repr(a) for a in args]
        kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()]
        signature = ", ".join(args_repr + kwargs_repr)
        print(f"Calling {func.__name__}({signature})")

        start = time.perf_counter()
        value = func(*args, **kwargs)
        end = time.perf_counter()
        print(f"{func.__name__} returned {value!r} in {end-start:.5f} secs")

        return value
    return wrapper_debug

@debug
def algorithm1(data):
    return sorted(data)

@debug
def algorithm2(data):
    return list(set(data))

data = [random.randint(0, 10) for _ in range(10)]

algorithm1(data)
algorithm2(data)
```

{% endcode %}

**執行結果:**

```txt
Calling algorithm1([2, 6, 1, 8, 6, 0, 7, 5, 10, 7])
algorithm1 returned [0, 1, 2, 5, 6, 6, 7, 7, 8, 10] in 0.00000 secs

Calling algorithm2([2, 6, 1, 8, 6, 0, 7, 5, 10, 7])
algorithm2 returned [0, 1, 2, 5, 6, 7, 8, 10] in 0.00000 secs
```

## 參考資料

***

[time — Time access and conversions — Python 3.11.4 documentation](https://docs.python.org/3/library/time.html#module-time)

[「耗時測試」python time包中的time()和process\_time()如何選擇？ - 資訊咖](https://inf.news/zh-hant/news/c73bc95076a8752dd3ce965d3a64fc40.html)

[Python 中的定時器函式 | D棧 - Delft Stack](https://www.delftstack.com/zh-tw/howto/python/python-timer-functions/)

[Python 實現計時器(不同方式)\_一顆小樹x - MdEditor](https://www.gushiciku.cn/pl/pEJ1/zh-tw)

[Python time 時間模組使用教學與範例 - Office 指南](https://officeguide.cc/python-time-tutorial-examples/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xiwind-corp.com/tech/python-library/time-shi-jian/sleep-fan-li-....md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
