> For the complete documentation index, see [llms.txt](https://docs.xiwind-corp.com/tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xiwind-corp.com/tech/python-library/time-shi-jian/sleep-fan-li-....md).

# 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/)
