Heim  >  Artikel  >  Backend-Entwicklung  >  Verschlüsse und Dekoratoren in Python beherrschen: Von den Grundlagen bis zum Fortgeschrittenen

Verschlüsse und Dekoratoren in Python beherrschen: Von den Grundlagen bis zum Fortgeschrittenen

DDD
DDDOriginal
2024-09-19 01:39:33497Durchsuche

Mastering Closures and Decorators in Python: From Basics to Advanced

Einführung

Closures und Decorators sind leistungsstarke Funktionen in Python, die es Ihnen ermöglichen, flexibleren und wiederverwendbareren Code zu schreiben. Wenn Sie diese Konzepte verstehen, werden Ihre Python-Kenntnisse auf die nächste Stufe gehoben, sodass Sie komplexere Szenarien wie Protokollierung, Zugriffskontrolle und Merken problemlos bewältigen können.

In diesem Blogbeitrag beschäftigen wir uns mit Folgendem:

  1. Was sind Schließungen?
  2. Verstehen, wie Schließungen in Python funktionieren
  3. Anwendungsfälle für Verschlüsse
  4. Was sind Dekorateure?
  5. Verstehen, wie Dekorateure arbeiten
  6. Verwendung integrierter Dekoratoren
  7. Benutzerdefinierte Dekorateure schreiben
  8. Fortgeschrittene Konzepte mit Dekorateuren

Am Ende dieses Artikels haben Sie ein solides Verständnis für Abschlüsse und Dekoratoren und können diese effektiv in Ihrem eigenen Code anwenden.

Was sind Schließungen?

In Python sind Abschlüsse Funktionen, die die Werte von Variablen aus ihrem umschließenden lexikalischen Bereich beibehalten, selbst wenn die Ausführung der äußeren Funktion abgeschlossen ist. Abschlüsse sind eine Möglichkeit, den Status zwischen Funktionsaufrufen beizubehalten, was sie für Szenarien nützlich macht, in denen Sie einen gewissen Kontext beibehalten müssen.

Abschlüsse bestehen aus drei Hauptkomponenten:

  1. Eine verschachtelte Funktion
  2. Ein Verweis auf eine freie Variable in der einschließenden Funktion
  3. Die Ausführung der einschließenden Funktion ist abgeschlossen, aber die verschachtelte Funktion merkt sich weiterhin den Status der freien Variablen.

Grundlegendes Beispiel für einen Abschluss

Hier ist ein Beispiel für einen einfachen Verschluss:

def outer_function(message):
    def inner_function():
        print(message)
    return inner_function

# Create a closure
closure = outer_function("Hello, World!")
closure()  # Output: Hello, World!

In diesem Beispiel verweist „inner_function“ auf die Nachrichtenvariable von „outer_function“, auch nachdem die Ausführung von „outer_function“ abgeschlossen ist. Die innere Funktion „schließt“ die Variable aus dem äußeren Bereich, daher der Begriff Abschluss.

Wie Schließungen intern funktionieren

Abschlüsse funktionieren, indem sie den Zustand freier Variablen erfassen und sie im __closure__-Attribut des Funktionsobjekts speichern.

Sehen wir uns den Abschluss aus dem vorherigen Beispiel an:

print(closure.__closure__[0].cell_contents)  # Output: Hello, World!

Das Attribut __closure__ enthält die Verweise auf die Variablen, die der Abschluss behält. Jede Variable wird in einer „Zelle“ gespeichert und Sie können mit cell_contents.

auf deren Inhalte zugreifen

Anwendungsfälle für Schließungen

Abschlüsse sind besonders nützlich, wenn Sie den Status zwischen Funktionsaufrufen beibehalten möchten, ohne globale Variablen oder Klassen zu verwenden. Hier sind einige häufige Anwendungsfälle:

1. Funktionsfabriken

Sie können Abschlüsse verwenden, um Funktionen dynamisch zu erstellen.

def multiplier(factor):
    def multiply_by_factor(number):
        return number * factor
    return multiply_by_factor

times_two = multiplier(2)
times_three = multiplier(3)

print(times_two(5))  # Output: 10
print(times_three(5))  # Output: 15

In diesem Beispiel gibt der Multiplikator eine Funktion zurück, die eine bestimmte Zahl mit einem bestimmten Faktor multipliziert. Die Abschlüsse times_two und times_ three behalten den Wert des Faktors aus ihrem umschließenden Bereich.

2. Einkapselung

Abschlüsse ermöglichen es Ihnen, Verhalten zu kapseln, ohne den internen Zustand offenzulegen. Dies ähnelt dem Konzept privater Methoden in der objektorientierten Programmierung.

def counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

counter_fn = counter()
print(counter_fn())  # Output: 1
print(counter_fn())  # Output: 2

In diesem Beispiel ist die Zählvariable im Abschluss gekapselt und nur die Inkrementierungsfunktion kann ihren Wert ändern.

Was sind Dekorateure?

Ein Dekorator ist eine Funktion, die eine andere Funktion übernimmt und deren Verhalten erweitert oder ändert, ohne den Code der ursprünglichen Funktion zu ändern. Dekoratoren werden häufig verwendet, um Funktionen und Methoden um Funktionen wie Protokollierung, Zugriffskontrolle oder Timing hinzuzufügen.

In Python werden Dekoratoren auf Funktionen angewendet, indem das @-Symbol über der Funktionsdefinition verwendet wird.

Grundlegendes Beispiel eines Dekorateurs

def decorator_function(original_function):
    def wrapper_function():
        print(f"Wrapper executed before {original_function.__name__}()")
        return original_function()
    return wrapper_function

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

say_hello()

# Output:
# Wrapper executed before say_hello()
# Hello!

Hier wird decorator_function auf say_hello angewendet und fügt zusätzliche Funktionalität hinzu, bevor say_hello() ausgeführt wird.

Wie Dekorateure arbeiten

Dekoratoren sind im Wesentlichen syntaktischer Zucker für ein allgemeines Muster in Python: Funktionen höherer Ordnung, die andere Funktionen als Argumente verwenden. Wenn Sie @decorator schreiben, entspricht dies:

say_hello = decorator_function(say_hello)

Die Dekoratorfunktion gibt eine neue Funktion (wrapper_function) zurück, die das Verhalten der ursprünglichen Funktion erweitert.

Dekorateure mit Argumenten

Wenn die Funktion, die dekoriert wird, Argumente akzeptiert, muss die Wrapper-Funktion *args und **kwargs akzeptieren, um die Argumente weiterzugeben.

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        print(f"Wrapper executed before {original_function.__name__}()")
        return original_function(*args, **kwargs)
    return wrapper_function

@decorator_function
def display_info(name, age):
    print(f"display_info ran with arguments ({name}, {age})")

display_info("John", 25)

# Output:
# Wrapper executed before display_info()
# display_info ran with arguments (John, 25)

Integrierte Dekoratoren in Python

Python bietet mehrere integrierte Dekoratoren, wie z. B. @staticmethod, @classmethod und @property.

@staticmethod and @classmethod

These decorators are commonly used in object-oriented programming to define methods that are either not bound to the instance (@staticmethod) or bound to the class itself (@classmethod).

class MyClass:
    @staticmethod
    def static_method():
        print("Static method called")

    @classmethod
    def class_method(cls):
        print(f"Class method called from {cls}")

MyClass.static_method()   # Output: Static method called
MyClass.class_method()    # Output: Class method called from <class '__main__.MyClass'>

@property

The @property decorator allows you to define a method that can be accessed like an attribute.

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value <= 0:
            raise ValueError("Radius must be positive")
        self._radius = value

c = Circle(5)
print(c.radius)  # Output: 5

c.radius = 10
print(c.radius)  # Output: 10

Writing Custom Decorators

You can write your own decorators to add custom functionality to your functions or methods. Decorators can be stacked, meaning you can apply multiple decorators to a single function.

Example: Timing a Function

Here’s a custom decorator that measures the execution time of a function:

import time

def timer_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} ran in {end_time - start_time:.4f} seconds")
        return result
    return wrapper

@timer_decorator
def calculate_square(numbers):
    result = [n * n for n in numbers]
    return result

nums = range(1, 1000000)
calculate_square(nums)

Decorators with Arguments

Decorators can also accept their own arguments. This is useful when you need to pass configuration values to the decorator.

Example: Logger with Custom Message

def logger_decorator(message):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"{message}: Executing {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@logger_decorator("DEBUG")
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

# Output:
# DEBUG: Executing greet
# Hello, Alice!

In this example, the decorator logger_decorator takes a message as an argument, and then it wraps the greet function with additional logging functionality.

Advanced Decorator Concepts

1. Decorating Classes

Decorators can be applied not only to functions but also to classes. Class decorators modify or extend the behavior of entire classes.

def add_str_repr(cls):
    cls.__str__ = lambda self: f"Instance of {cls.__name__}"
    return cls

@add_str_repr
class Dog:
    pass

dog = Dog()
print(dog)  # Output: Instance of Dog

2. Memoization with Decorators

Memoization is an optimization technique where the results of expensive function calls are cached, so subsequent calls with the same arguments can be returned faster.

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

@memoize
def fibonacci(n):


 if n in [0, 1]:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(30))  # Output: 832040

Conclusion

Closures and decorators are advanced Python concepts that unlock powerful capabilities for writing cleaner, more efficient code. Closures allow you to maintain state and encapsulate data, while decorators let you modify or extend the behavior of functions and methods in a reusable way. Whether you're optimizing performance with memoization, implementing access control, or adding logging, decorators are an essential tool in your Python toolkit.

By mastering these concepts, you'll be able to write more concise and maintainable code and handle complex programming tasks with ease.

Feel free to experiment with closures and decorators in your projects and discover how they can make your code more elegant and powerful!


Connect with Me

  • GitHub
  • Linkedin

Das obige ist der detaillierte Inhalt vonVerschlüsse und Dekoratoren in Python beherrschen: Von den Grundlagen bis zum Fortgeschrittenen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn