自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

五分鐘理解Python裝飾器,讓代碼更優(yōu)雅

開發(fā)
通過(guò)掌握基礎(chǔ)裝飾器、參數(shù)化裝飾器、裝飾器鏈,以及實(shí)現(xiàn)特定功能如緩存的高級(jí)應(yīng)用,你將能夠編寫出更加優(yōu)雅和高效的Python程序。

什么是裝飾器?

想象一下,你有一個(gè)漂亮的房間,但你想讓它看起來(lái)更加特別,于是你決定掛上一些裝飾畫。在編程的世界里,Python裝飾器就是那些“裝飾畫”,它們能讓你的函數(shù)或類“房間”看起來(lái)或工作得更加出色,而無(wú)需改變其內(nèi)部結(jié)構(gòu)。

def say_hello(name):
    print(f"Hello, {name}!")

# 這就是我們的裝飾畫
def fancy_decorator(func):
    def wrapper():
        print("Adding some fancy touch...")
        func()
        print("Decoration ends here.")
    return wrapper

# 掛上裝飾畫
fancy_say_hello = fancy_decorator(say_hello)

fancy_say_hello("World")

輸出:

Adding some fancy touch...
Hello, World!
Decoration ends here.

這段代碼中,fancy_decorator就是一個(gè)裝飾器,它包裝了原始的say_hello函數(shù),給它加上了前后打印信息的功能。

裝飾器的魔法

裝飾器的“魔法”在于它們使用了函數(shù)的高階特性,即函數(shù)可以接受另一個(gè)函數(shù)作為參數(shù),并返回一個(gè)新的函數(shù)。當(dāng)你在函數(shù)定義前使用@符號(hào),實(shí)際上是執(zhí)行了一個(gè)賦值操作,將裝飾器的結(jié)果賦予了原函數(shù)名。

@fancy_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

輸出:

Adding some fancy touch...
Hello, Alice!
Decoration ends here.

這里,@fancy_decorator等同于手動(dòng)執(zhí)行了say_hello = fancy_decorator(say_hello),使得每次調(diào)用say_hello時(shí),都會(huì)先經(jīng)過(guò)fancy_decorator的處理。

參數(shù)化的裝飾器

有時(shí)候,裝飾器也需要根據(jù)不同的情況調(diào)整行為,這就需要參數(shù)化的裝飾器。

def repeat(n):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat

@repeat(3)
def greet(name):
    print(f"Hi, {name}")

greet("Bob")

輸出:

Hi, Bob
Hi, Bob
Hi, Bob

這里,repeat是一個(gè)參數(shù)化的裝飾器工廠,它接收一個(gè)參數(shù)n,并返回一個(gè)具體的裝飾器,這個(gè)裝飾器會(huì)讓被裝飾的函數(shù)重復(fù)執(zhí)行n次。

高級(jí)裝飾器技巧:帶參數(shù)的進(jìn)階

之前提到的參數(shù)化裝飾器,其實(shí)還可以做得更靈活。如果想要裝飾器本身能夠接收多個(gè)參數(shù),可以通過(guò)額外的閉包層來(lái)實(shí)現(xiàn)。

def with_args(arg1, arg2):
    def decorator_with_args(func):
        def wrapper(*args, **kwargs):
            print(f"Using arguments: {arg1}, {arg2}")
            return func(*args, **kwargs)
        return wrapper
    return decorator_with_args

@with_args('A', 'B')
def show_args():
    print("Inside the function")

show_args()

輸出:

Using arguments: A, B
Inside the function

這里,with_args不僅能夠裝飾函數(shù),還能在裝飾時(shí)接收參數(shù),實(shí)現(xiàn)了高度的定制化。

裝飾器鏈:復(fù)合裝飾器的力量

裝飾器可以堆疊使用,形成裝飾器鏈,為函數(shù)添加多層功能。

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Function {func.__name__} is called")
        return func(*args, **kwargs)
    return wrapper

def timer_decorator(func):
    import time
    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:.2f} seconds")
        return result
    return wrapper

@log_decorator
@timer_decorator
def example_function(n):
    sum(range(n))

example_function(10000)

輸出示例:

Function example_function is called
example_function took 0.00 seconds

通過(guò)這種方式,我們可以輕松地為函數(shù)添加日志記錄、性能測(cè)試等多種功能,且各裝飾器之間的功能相互獨(dú)立,易于維護(hù)。

實(shí)戰(zhàn)案例:緩存機(jī)制

讓我們來(lái)看一個(gè)實(shí)用場(chǎng)景——使用裝飾器實(shí)現(xiàn)函數(shù)結(jié)果的緩存,以提高效率。

def cache_decorator(func):
    cache = {}
    
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    
    return wrapper

@cache_decorator
def fibonacci(n):
    if n <= 1:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))
print(fibonacci(10)) # 第二次調(diào)用應(yīng)該更快

在這個(gè)例子中,cache_decorator裝飾器用于存儲(chǔ)fibonacci函數(shù)的計(jì)算結(jié)果,避免重復(fù)計(jì)算,顯著提高了遞歸計(jì)算斐波那契數(shù)列的效率。

總結(jié)與實(shí)踐技巧

裝飾器是Python編程中的高級(jí)技巧,它們讓代碼更加簡(jiǎn)潔、模塊化。通過(guò)掌握基礎(chǔ)裝飾器、參數(shù)化裝飾器、裝飾器鏈,以及實(shí)現(xiàn)特定功能如緩存的高級(jí)應(yīng)用,你將能夠編寫出更加優(yōu)雅和高效的Python程序。

  • 練習(xí)技巧:嘗試為自己的函數(shù)編寫裝飾器,比如計(jì)時(shí)裝飾器,用于監(jiān)控函數(shù)執(zhí)行時(shí)間。
  • 方法提示:在設(shè)計(jì)裝飾器時(shí),考慮其通用性和可擴(kuò)展性,以便在多個(gè)場(chǎng)景下重用。
  • 使用技巧:注意裝飾器的執(zhí)行順序是從下往上,這影響著函數(shù)最終的行為。
  • 注意事項(xiàng):對(duì)于有狀態(tài)的裝飾器,要小心管理狀態(tài),避免在并發(fā)環(huán)境下產(chǎn)生意料之外的行為。
責(zé)任編輯:趙寧寧 來(lái)源: PythonAI與圖像處理
相關(guān)推薦

2024-09-03 09:47:09

閉包裝飾器Python

2011-08-08 09:22:10

Python

2024-09-18 08:21:24

JavaScriptTypeScriptprototype

2009-11-06 16:05:37

WCF回調(diào)契約

2023-07-26 07:11:50

LVM底層抽象

2024-02-21 21:19:18

切片Python語(yǔ)言

2024-07-12 14:21:32

Python編碼

2020-04-03 14:55:39

Python 代碼編程

2009-10-29 11:39:52

ADO.NET連接池

2023-12-06 08:48:36

Kubernetes組件

2009-11-05 10:56:31

WCF通訊

2024-07-10 18:55:09

Python定時(shí)

2024-07-03 08:13:56

規(guī)則執(zhí)行器代碼

2009-11-16 11:30:55

PHP上傳文件代碼

2022-03-08 06:41:35

css代碼

2017-12-20 09:42:39

PythonNginx日志

2020-05-12 09:10:24

瀏覽器服務(wù)器網(wǎng)絡(luò)

2009-11-04 16:13:18

ADO.NET數(shù)據(jù)表

2009-11-16 10:53:30

Oracle Hint

2024-12-11 07:00:00

面向?qū)ο?/a>代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)