成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python 如何在裝飾器中使用其他函數?

開發 前端
在裝飾器中使用其他函數是一種常見的需求,可以幫助你將復雜的功能分解成更小、更易于管理的部分。

前言

在裝飾器中使用其他函數是一種常見的需求,可以幫助你將復雜的功能分解成更小、更易于管理的部分。

使用輔助函數進行日志記錄

假設你有一個裝飾器,用于在函數調用前后記錄日志。你可以將日志記錄的功能提取到一個單獨的輔助函數中。

import logging
# 配置日志記錄
logging.basicConfig(level=logging.INFO)
def log_message(message):
    logging.info(message)
def log_function_call(func):
    def wrapper(*args, **kwargs):
        log_message(f"Calling {func.__name__} with args={args} kwargs={kwargs}")
        result = func(*args, **kwargs)
        log_message(f"{func.__name__} returned {result}")
        return result
    return wrapper
@log_function_call
def add(a, b):
    return a + b
add(3, 5)

使用輔助函數進行輸入驗證

假設你有一個裝飾器,用于驗證函數的輸入參數。你可以將輸入驗證的邏輯提取到一個單獨的輔助函數中。

def validate_input(*types):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if len(args) != len(types):
                raise TypeError("Number of arguments does not match expected types")
            for arg, type_ in zip(args, types):
                if not isinstance(arg, type_):
                    raise TypeError(f"Argument {arg} is not of type {type_}")
            return func(*args, **kwargs)
        return wrapper
    return decorator
def is_positive(number):
    if number <= 0:
        raise ValueError("Number must be positive")
    return number
@validate_input(int, int)
def add(a, b):
    return a + b
@validate_input(int)
def square(n):
    return n ** 2
add(3, 5)  # 正常運行
square(4)  # 正常運行
# square(-4)  # 拋出 ValueError

使用輔助函數進行緩存

假設你有一個裝飾器,用于緩存函數的結果。你可以將緩存的邏輯提取到一個單獨的輔助函數中。

from functools import lru_cache
def cache_results(func):
    @lru_cache(maxsize=128)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper
def compute_fibonacci(n):
    if n <= 1:
        return n
    return compute_fibonacci(n - 1) + compute_fibonacci(n - 2)
@cache_results
def fibonacci(n):
    return compute_fibonacci(n)
print(fibonacci(10))  # 輸出: 55
print(fibonacci(10))  # 直接從緩存中獲取結果

使用輔助函數進行權限驗證

假設你有一個裝飾器,用于驗證用戶是否有權限調用某個函數。你可以將權限驗證的邏輯提取到一個單獨的輔助函數中。

def check_permission(permission):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if not has_permission(permission):
                raise PermissionError(f"User does not have permission {permission}")
            return func(*args, **kwargs)
        return wrapper
    return decorator
def has_permission(permission):
    # 假設這里有一個權限檢查的邏輯
    return permission == "admin"
@check_permission("admin")
def admin_action():
    print("Performing admin action")
@check_permission("user")
def user_action():
    print("Performing user action")
admin_action()  # 正常運行
# user_action()  # 拋出 PermissionError

使用輔助函數進行性能測量

假設你有一個裝飾器,用于測量函數的執行時間。你可以將性能測量的邏輯提取到一個單獨的輔助函數中。

import time
def measure_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.4f} seconds to execute")
        return result
    return wrapper
def get_current_time():
    return time.time()
@measure_time
def slow_function():
    time.sleep(2)
    print("Slow function completed")
slow_function()

如何在裝飾器中使用多個裝飾器?

基本的多重裝飾器

假設你有兩個裝飾器 @log_function_call 和 @measure_time,分別用于日志記錄和性能測量。

import logging
import time
# 配置日志記錄
logging.basicConfig(level=logging.INFO)
def log_message(message):
    logging.info(message)
def log_function_call(func):
    def wrapper(*args, **kwargs):
        log_message(f"Calling {func.__name__} with args={args} kwargs={kwargs}")
        result = func(*args, **kwargs)
        log_message(f"{func.__name__} returned {result}")
        return result
    return wrapper
def measure_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.4f} seconds to execute")
        return result
    return wrapper
@log_function_call
@measure_time
def add(a, b):
    time.sleep(1)  # 模擬耗時操作
    return a + b
result = add(3, 5)
print(f"Result: {result}")

帶參數的多重裝飾器

假設你有一個帶參數的裝飾器 @repeat,用于多次調用函數,同時還有一個 @log_function_call 裝飾器。

import logging
# 配置日志記錄
logging.basicConfig(level=logging.INFO)
def log_message(message):
    logging.info(message)
def log_function_call(func):
    def wrapper(*args, **kwargs):
        log_message(f"Calling {func.__name__} with args={args} kwargs={kwargs}")
        result = func(*args, **kwargs)
        log_message(f"{func.__name__} returned {result}")
        return result
    return wrapper
def repeat(num_times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            results = []
            for _ in range(num_times):
                result = func(*args, **kwargs)
                results.append(result)
            return results
        return wrapper
    return decorator
@log_function_call
@repeat(3)
def greet(name):
    return f"Hello, {name}!"
results = greet("Alice")
for result in results:
    print(result)

使用 functools.wraps 保留元數據

為了保留被裝飾函數的元數據(如名稱、文檔字符串等),可以使用 functools.wraps。

import logging
import time
import functools
# 配置日志記錄
logging.basicConfig(level=logging.INFO)
def log_message(message):
    logging.info(message)
def log_function_call(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        log_message(f"Calling {func.__name__} with args={args} kwargs={kwargs}")
        result = func(*args, **kwargs)
        log_message(f"{func.__name__} returned {result}")
        return result
    return wrapper
def measure_time(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.4f} seconds to execute")
        return result
    return wrapper
@log_function_call
@measure_time
def add(a, b):
    time.sleep(1)  # 模擬耗時操作
    return a + b
result = add(3, 5)
print(f"Result: {result}")
print(add.__name__)  # 輸出: add
print(add.__doc__)   # 輸出: None 或者函數的文檔字符串

組合多個帶參數的裝飾器

假設你有兩個帶參數的裝飾器 @repeat 和 @log_level,分別用于多次調用函數和設置日志級別。

import logging
import functools
# 配置日志記錄
logging.basicConfig(level=logging.DEBUG)
def set_log_level(level):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            logger = logging.getLogger(func.__name__)
            logger.setLevel(level)
            result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator
def repeat(num_times):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            results = []
            for _ in range(num_times):
                result = func(*args, **kwargs)
                results.append(result)
            return results
        return wrapper
    return decorator
@set_log_level(logging.INFO)
@repeat(3)
def greet(name):
    logger = logging.getLogger(greet.__name__)
    logger.info(f"Greeting {name}")
    return f"Hello, {name}!"
results = greet("Alice")
for result in results:
    print(result)

總結

通過將裝飾器中的復雜邏輯提取到單獨的輔助函數中,可以使裝飾器更加模塊化和易于維護。這些輔助函數可以被多個裝飾器復用,從而提高代碼的重用性和可讀性。

通過組合多個裝飾器,可以實現更復雜的功能。多個裝飾器的執行順序是從內到外,因此最靠近函數定義的裝飾器會首先被應用。使用 functools.wraps 可以保留被裝飾函數的元數據,使代碼更加清晰和易讀。希望這些示例能幫助你更好地理解如何在裝飾器中使用多個裝飾器。

責任編輯:華軒 來源: 測試開發學習交流
相關推薦

2022-05-10 09:12:16

TypeScript裝飾器

2010-02-01 17:50:32

Python裝飾器

2022-06-23 08:00:53

PythonDateTime模塊

2023-02-27 17:36:33

LinuxSIGINT信號

2022-10-13 00:03:00

JavaScripSQL函數

2020-09-09 07:00:00

TensorFlow神經網絡人工智能

2025-03-21 09:58:59

Python數據類型安全

2023-02-07 07:47:52

Python裝飾器函數

2023-08-24 10:24:54

GitLabPodman

2010-03-10 14:03:41

python處理文本

2025-01-20 08:40:00

Python對象

2020-12-08 22:07:08

PythonWebDjango

2019-09-16 19:00:48

Linux變量

2020-11-30 11:55:07

Docker命令Linux

2014-07-02 09:47:06

SwiftCocoaPods

2020-04-09 10:18:51

Bash循環Linux

2024-09-06 11:34:15

RustAI語言

2022-05-17 08:25:10

TypeScript接口前端

2021-06-09 09:36:18

DjangoElasticSearLinux

2021-03-09 07:27:40

Kafka開源分布式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 青青久久| 亚洲成人二区 | 福利视频日韩 | 成人久久久 | 欧美精品一区二区在线观看 | 日本小视频网站 | 九九色综合 | 久久夜视频 | 一区二区三区四区视频 | 久久亚洲视频 | 欧美jizzhd精品欧美巨大免费 | 国产精品日日摸夜夜添夜夜av | 久久久久国产一区二区三区不卡 | 日韩高清中文字幕 | 99亚洲精品| 久久与欧美 | 国产专区在线 | 狠狠骚 | 久久精品国产久精国产 | 亚洲成人一二区 | 欧美在线视频二区 | 国产中文字幕在线 | 免费视频一区 | 91免费观看视频 | 久久免费精品视频 | 国产精品久久久久久久免费大片 | 久久久久久久av | 九色视频网站 | 久久久91精品国产一区二区精品 | 91免费电影 | 亚洲最新在线视频 | 2019中文字幕视频 | av天空| 久草免费福利 | 久久av一区二区三区 | 国产成人精品一区二区 | 久久久久久久国产精品 | 久久国产一区 | 国产高清精品一区二区三区 | 色婷婷综合久久久中字幕精品久久 | 国产精品一区二区av |