Slik bruker du Python-dekoratorer for å forbedre funksjoner

Python-dekoratorer er en kraftig og fleksibel måte å modifisere eller forbedre funksjoner og metoder. Dekoratorer gir en måte å pakke inn en funksjon med ekstra funksjonalitet, slik at du kan utvide funksjonen uten å endre den faktiske koden. Denne artikkelen vil introdusere deg til konseptet med dekoratører, hvordan du lager og bruker dem, og utforske noen praktiske eksempler.

Hva er en dekoratør?

En dekoratør er en funksjon som tar en annen funksjon og utvider dens oppførsel uten å eksplisitt endre den. I Python brukes dekoratører ofte for å legge til funksjonalitet som logging, tilgangskontroll eller ytelsesmåling til eksisterende funksjoner eller metoder. Dekoratorer brukes på funksjoner ved å bruke syntaksen @decorator_name.

# Basic example of a decorator
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

Slik fungerer dekoratører

Når du bruker en dekoratør på en funksjon, utfører Python i hovedsak følgende trinn:

  1. Dekoratorfunksjonen kalles med den opprinnelige funksjonen som argument.
  2. Dekoratorfunksjonen definerer en ny funksjon (ofte kalt wrapper) som forbedrer eller modifiserer virkemåten til den opprinnelige funksjonen.
  3. Dekoratorfunksjonen returnerer den nye funksjonen.
  4. Når den dekorerte funksjonen kalles, kaller den faktisk den nye funksjonen returnert av dekoratøren.

Opprette en enkel dekoratør

La oss lage en enkel dekoratør som måler utførelsestiden til en funksjon. Dette er nyttig for ytelsestesting og optimalisering.

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Execution time: {end_time - start_time} seconds")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)
    print("Function finished!")

slow_function()

Bruk av dekoratører med argumenter

Noen ganger vil du kanskje sende argumenter til dekoratøren din. For å oppnå dette må du opprette en dekoratørfabrikk – en funksjon som returnerer en dekoratør. Her er et eksempel på en dekoratør som tar et argument for å spesifisere en tilpasset melding.

def custom_message_decorator(message):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(message)
            return func(*args, **kwargs)
        return wrapper
    return decorator

@custom_message_decorator("Starting the function...")
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

Dekoratører for metoder i klassene

Dekoratorer kan også brukes med metoder inne i klassene. Vanlige bruksområder inkluderer loggingsmetodeanrop, tilgangskontroll og hurtigbufferresultater. Her er et eksempel på bruk av en dekoratør til å logge metodekall i en klasse.

def log_method_call(method):
    def wrapper(self, *args, **kwargs):
        print(f"Calling {method.__name__} with arguments {args} and keyword arguments {kwargs}")
        return method(self, *args, **kwargs)
    return wrapper

class MyClass:
    @log_method_call
    def my_method(self, x, y):
        print(f"Result: {x + y}")

obj = MyClass()
obj.my_method(5, 7)

Kjededekoratører

Du kan bruke flere dekoratører til en enkelt funksjon. De påføres fra den innerste dekoratøren til den ytterste. Dette lar deg komponere forskjellige funksjoner sammen. Her er et eksempel på å lenke to dekoratører:

def uppercase_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

def exclamation_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result + "!"
    return wrapper

@exclamation_decorator
@uppercase_decorator
def greet(name):
    return f"Hello, {name}"

print(greet("Alice"))

Konklusjon

Dekoratorer er et allsidig verktøy i Python som lar deg forbedre eller endre oppførselen til funksjoner og metoder. Ved å bruke dekoratører kan du legge til gjenbrukbar funksjonalitet på tvers av kodebasen din uten å endre kjernelogikken til funksjonene dine. Enten for logging, timing eller endring av utdata, hjelper dekoratører med å holde koden din ren og vedlikeholdbar. Øv deg på å bruke dekoratører for å bli dyktigere og utnytte kraften deres i Python-prosjektene dine.