Heim  >  Artikel  >  Backend-Entwicklung  >  Eindrucksvoll! Empfehlen Sie acht coole Python-Dekoratoren!

Eindrucksvoll! Empfehlen Sie acht coole Python-Dekoratoren!

WBOY
WBOYnach vorne
2023-04-19 11:49:031432Durchsuche

Eindrucksvoll! Empfehlen Sie acht coole Python-Dekoratoren!

Vorwort

Eines der großartigen Dinge an der Programmiersprache Python ist, dass sie alle Funktionen in einem kleinen Paket verpackt, die sehr nützlich sind.

Viele Funktionen können die Funktionalität von Python-Code vollständig verändern und die Sprache dadurch noch flexibler machen. Bei richtiger Anwendung können einige dieser Funktionen die zum Schreiben eines Programms erforderliche Zeit effektiv verkürzen.

Ein großartiges Beispiel für das Erreichen dieser Ziele sind die Dekoratoren von Python.

Decorators

Ein Decorator ist eine Funktion, mit der das Verhalten eines Python-Funktionsobjekts geändert werden kann. Sie können auf Klassen und Funktionen angewendet werden und viele wirklich interessante Dinge bewirken!

Dekoratoren können verwendet werden, um Ihren Code zu verkürzen, ihn zu beschleunigen und das Verhalten Ihres Codes in Python vollständig zu ändern.

Das ist natürlich praktisch! Heute möchte ich einige Dekorateure vorstellen, die meiner Meinung nach einen Blick wert sind.

Es gibt viele Dekorateure, aber ich habe einige ausgewählt, die meiner Meinung nach die coolsten Funktionen haben.

1. @lru_cache

Der erste Dekorator in dieser Liste stammt aus dem Functools-Modul.

Dieses Modul ist in der Standardbibliothek enthalten und sehr einfach zu verwenden. Es enthält auch coolere Funktionen als dieser Dekorator, aber dieser Dekorator ist definitiv mein Favorit.

Dieser Dekorator kann verwendet werden, um die kontinuierliche Ausführung einer Funktion mithilfe von Caching zu beschleunigen. Natürlich sollte dies unter Berücksichtigung einiger Einschränkungen hinsichtlich des Cachings verwendet werden, aber in allgemeinen Anwendungsfällen lohnt sich die Verwendung dieses Dekorators in den meisten Fällen.

Es ist großartig, Ihren Code mit einem einfachen Dekorator beschleunigen zu können.

Ein gutes Beispiel für eine Funktion, die von einem solchen Dekorator profitieren kann, ist eine rekursive Funktion, beispielsweise eine Funktion, die Fakultäten berechnet:

def factorial(n):
 return n * factorial(n-1) if n else 1

Rekursion kann in Bezug auf die Rechenzeit sehr schwierig sein, aber das Hinzufügen dieses Dekorators hilft, dies zu zeigen Um den kontinuierlichen Betrieb dieser Funktion zu beschleunigen.

@lru_cache
def factorial(n):
 return n * factorial(n-1) if n else 1

Wenn wir nun diese Funktion ausführen, werden die ersten paar faktoriellen Berechnungen im Cache gespeichert.

Wenn wir diese Funktion also das nächste Mal aufrufen, müssen wir nur die Fakultät nach der Fakultät berechnen, die wir zuvor verwendet haben.

Natürlich werden nicht alle faktoriellen Berechnungen gespeichert, aber es ist leicht zu verstehen, warum dieser Decorator eine gute Anwendung ist, um von Natur aus langsamen Code zu beschleunigen.

2. @jit

JIT ist die Abkürzung für Just In Time. Wenn wir Code in Python ausführen, geschieht normalerweise als Erstes die Kompilierung.

Diese Kompilierung verursacht einen gewissen Overhead, da den Typen Speicher zugewiesen und als nicht zugewiesene, aber benannte Aliase gespeichert wird. Bei der Just-in-Time-Kompilierung kompilieren wir nur zur Ausführungszeit.

In vielerlei Hinsicht können wir uns das als etwas Ähnliches wie paralleles Rechnen vorstellen, bei dem der Python-Interpreter zwei Dinge gleichzeitig erledigt, um etwas Zeit zu sparen.

Der Numba JIT-Compiler ist dafür bekannt, dieses Konzept auf Python zu übertragen. Ähnlich wie @lru_cache kann dieser Dekorator sehr einfach aufgerufen werden und die Leistung Ihres Codes sofort verbessern. Das Numba-Paket bietet JIT-Dekoratoren, die es einfacher machen, anspruchsvollere Software auszuführen, ohne auf C umsteigen zu müssen.

Im folgenden Fall wird der @jit-Dekorator verwendet, um Berechnungen mit der Monte-Carlo-Methode zu beschleunigen.

from numba import jit
import random
@jit(nopython=True)
def monte_carlo_pi(nsamples):
 acc = 0
 for i in range(nsamples):
 x = random.random()
 y = random.random()
 if (x ** 2 + y ** 2) < 1.0:
 acc += 1
 return 4.0 * acc / nsamples

3. @do_twice

Der do_twice Decorator macht genau das, was sein Name vermuten lässt. Mit diesem Dekorator kann eine Funktion mit einem Aufruf zweimal ausgeführt werden. Dies hat sicherlich einige Verwendungsmöglichkeiten, ich finde es besonders nützlich zum Debuggen.

Es kann verwendet werden, um die Leistung von zwei verschiedenen Iterationen zu messen. Am Beispiel von Functools können wir eine Funktion zweimal ausführen, um nach Verbesserungen zu suchen. Diese Funktion wird vom Decorator-Modul in Python bereitgestellt, das sich in der Standardbibliothek befindet.

from decorators import do_twice
@do_twice
def timerfunc():
%timeit factorial(15)

4. @count_calls

Mit dem decorator count_calls können Informationen darüber bereitgestellt werden, wie oft eine Funktion in der Software verwendet wird.

Wie do_twice kann dies beim Debuggen sicherlich nützlich sein.

Beim Hinzufügen zu einer bestimmten Funktion erhalten wir eine Ausgabe, die uns bei jeder Ausführung mitteilt, wie oft die Funktion ausgeführt wurde. Dieser Dekorator befindet sich auch im Dekoratormodul der Standardbibliothek.

from decorators import count_calls
@count_calls
def function_example():
print("Hello World!")
function_example()
function_example()
function_example()

5. @dataclass

Um Zeit beim Schreiben von Kursen zu sparen, ist einer der besten Dekoratoren, die ich je verwendet habe, der @dataclass-Dekorator.

Mit diesem Dekorator können Sie schnell gängige Standardmethoden in Klassen schreiben, die normalerweise in den von uns geschriebenen Klassen zu finden sind.

Dieser Dekorator stammt aus dem Dataclass-Modul. Dieses Modul befindet sich auch in der Standardbibliothek, sodass zum Ausprobieren dieses Beispiels kein PIP erforderlich ist!

from dataclasses import dataclass
@dataclass
class Food:
name: str
unit_price: float
stock: int = 0
 def stock_value(self) -> float:
 return(self.stock * self.unit_price)

Dieser Code erstellt automatisch eine Initialisierungsfunktion init() mit den Positionsparametern, die zum Auffüllen der Daten in der Klasse erforderlich sind.

Sie werden auch automatisch für mich selbst bereitgestellt, sodass keine lange Funktion geschrieben werden muss, um einige Datenparameter in die Klasse einzufügen.

6. @singleton

Um den Zweck des Singleton-Dekorators zu verstehen, müssen wir zunächst verstehen, was ein Singleton ist. In gewissem Sinne sind Singletons eine Version globaler Variablentypen.

这意味着类型被定义为只存在一次。尽管这些在 C++ 等语言中很常见,但在 Python 中却很少见到。使用单例,我们可以创建一个只使用一次的类并改变类,而不是通过初始化来构造新的类型。

通常,单例装饰器是由用户自己编写的,实际上并不是导入的。

这是因为单例仍然是对我们单例装饰器中提供的模板的引用。我们可以命名一个单例函数并编写一个包装器,以便在我们的类上使用这个装饰器:

def singleton(cls):
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class cls:
def func(self):

另一种方法是使用元类!

7. @use_unit

在科学计算中经常派上用场的一种装饰器是 @use_unit 装饰器。

此装饰器可用于更改返回结果的表示单位。这对于那些不想在数据中添加度量单位但仍希望人们知道这些单位是什么的人很有用。

这个装饰器也不是在任何模块中真正可用,但它是非常常见的,对科学应用程序非常有用。

def use_unit(unit):
"""Have a function return a Quantity with given unit"""
use_unit.ureg = pint.UnitRegistry()
def decorator_use_unit(func):
@functools.wraps(func)
def wrapper_use_unit(*args, **kwargs):
value = func(*args, *_kwargs)
return value _ use_unit.ureg(unit)
return wrapper_use_unit
return decorator_use_unit
@use_unit("meters per second")
def average_speed(distance, duration):
return distance / duration

8. @singledispatch

Functools 凭借非常有用的@singledispatch 装饰器再次在此列表中脱颖而出。

单调度是一种编程技术,在许多编程语言中都很常见,因为它是一种非常棒的编程方式。虽然我更喜欢多调度,但我认为单调度可以在很多方面扮演相同的角色。

这个装饰器使得在 Python 中使用多类型数据变得更加容易, 尤其当我们希望通过同一方法传递多种类型数据时,情况更是如此。

@singledispatch
def fun(arg, verbose=False):
if verbose:
print("Let me just say,", end=" ")
print(arg)
@fun.register
def _(arg: int, verbose=False):
if verbose:
print("Strength in numbers, eh?", end=" ")
print(arg)
@fun.register
def _(arg: list, verbose=False):
if verbose:
print("Enumerate this:")
for i, elem in enumerate(arg):
print(i, elem)

Das obige ist der detaillierte Inhalt vonEindrucksvoll! Empfehlen Sie acht coole Python-Dekoratoren!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:51cto.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen