Afbeelding door redacteur
Python is, met zijn duidelijke en leesbare syntaxis, een veelgebruikte programmeertaal op hoog niveau. Python is ontworpen met het oog op gebruiksgemak, waarbij de nadruk wordt gelegd op eenvoud en lagere kosten voor programma-onderhoud. Het wordt geleverd met een uitgebreide bibliotheek die de noodzaak voor ontwikkelaars om vanaf het begin code te schrijven vermindert en de productiviteit van ontwikkelaars verhoogt. Een krachtig kenmerk van Python dat bijdraagt aan code-elegantie zijn decorateurs.
In Python is een decorateur een functie waarmee je het gedrag van een andere functie kunt wijzigen zonder de kernlogica ervan te veranderen. Het neemt een andere functie als argument en retourneert de functie met uitgebreide functionaliteit. Op deze manier kunt u decorateurs gebruiken om wat extra logica aan bestaande functies toe te voegen en de herbruikbaarheid met slechts een paar regels code te vergroten. In dit artikel zullen we acht ingebouwde Python-decorateurs verkennen die u kunnen helpen elegantere en onderhoudbare code te schrijven.
Afbeelding door redacteur
De @atexit.register
decorateur wordt gebruikt om een functie te registreren die moet worden uitgevoerd bij het beëindigen van het programma. Deze functie kan worden gebruikt om elke taak uit te voeren wanneer het programma op het punt staat af te sluiten, ongeacht of dit het gevolg is van een normale uitvoering of van een onverwachte fout.
Voorbeeld:
import atexit
# Register the exit_handler function
@atexit.register
def exit_handler():
print("Exiting the program. Cleanup tasks can be performed here.")
# Rest of the program
def main():
print("Inside the main function.")
# Your program logic goes here.
if __name__ == "__main__":
main()
Output:
Inside the main function.
Exiting the program. Cleanup tasks can be performed here.
In de bovenstaande implementatie @atexit.register
wordt boven de functiedefinitie vermeld. Het definieert de exit_handler()
fungeren als exitfunctie. In wezen betekent dit dat wanneer het programma zijn eindpunt bereikt, hetzij door normale uitvoering, hetzij door een onverwachte fout die een voortijdige afsluiting veroorzaakt, het programma het eindpunt bereikt. exit_handler()
functie zal worden aangeroepen.
De @dataclasses.dataclass
is een krachtige decorateur die wordt gebruikt om automatisch algemene speciale methoden te genereren voor klassen zoals “__init__”, “__repr__” en andere. Het helpt u schonere, beknoptere code te schrijven door de noodzaak te elimineren om standaardmethoden te schrijven voor het initialiseren en vergelijken van instanties van uw klasse. Het kan ook helpen fouten te voorkomen door ervoor te zorgen dat algemene speciale methoden consistent in uw codebase worden geïmplementeerd.
Voorbeeld:
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
point = Point(x=3, y=2)
# Printing object
print(point)
# Checking for the equality of two objects
point1 = Point(x=1, y=2)
point2 = Point(x=1, y=2)
print(point1 == point2)
Output:
Point(x=3, y=2)
True
De @dataclass
decorateur, toegepast boven de klassedefinitie Point, signaleert Python om standaardgedrag te gebruiken voor het genereren van speciale methoden. Hierdoor wordt automatisch de __init__
methode, die klassekenmerken, zoals x en y, initialiseert bij het instantiëren van objecten. Als gevolg hiervan kunnen instanties als point worden geconstrueerd zonder dat expliciete codering nodig is. Bovendien is de __repr__
De methode, die verantwoordelijk is voor het leveren van een stringrepresentatie van objecten, wordt ook automatisch aangepast. Dit zorgt ervoor dat wanneer een object, zoals een punt, wordt afgedrukt, dit een duidelijke en geordende weergave oplevert, zoals te zien in de uitvoer: Point(x=3, y=2). Bovendien levert de gelijkheidsvergelijking (==) tussen twee instanties, punt1 en punt2, True op. Dit is opmerkelijk omdat Python standaard controleert op gelijkheid op basis van de geheugenlocatie. In de context van dataclass-objecten wordt de gelijkheid echter bepaald door de gegevens die zich daarin bevinden. Dit komt omdat de @dataclass-decorateur een __eq__
methode die controleert op de gelijkheid van de gegevens in de objecten, in plaats van te controleren op dezelfde geheugenlocatie.
De @enum.unique
decorateur, te vinden in de enum-module, wordt gebruikt om ervoor te zorgen dat de waarden van alle leden van een opsomming uniek zijn. Dit helpt voorkomen dat er per ongeluk meerdere opsommingsleden met dezelfde waarde worden aangemaakt, wat tot verwarring en fouten kan leiden. Als er dubbele waarden worden gevonden, a ValueError wordt verhoogd.
Voorbeeld:
from enum import Enum, unique
@unique
class VehicleType(Enum):
CAR = 1
TRUCK = 2
MOTORCYCLE = 3
BUS = 4
# Attempting to create an enumeration with a duplicate value will raise a ValueError
try:
@unique
class DuplicateVehicleType(Enum):
CAR = 1
TRUCK = 2
MOTORCYCLE = 3
# BUS and MOTORCYCLE have duplicate values
BUS = 3
except ValueError as e:
print(f"Error: {e}")
Output:
Error: duplicate values found in : BUS -> MOTORCYCLE
In de bovenstaande implementatie hebben “BUS” en “MOTORFIETS” dezelfde waarde “3”. Als gevolg hiervan is de @unique
decorateur genereert een ValueError met een bericht dat aangeeft dat er dubbele waarden zijn gevonden. U kunt dezelfde sleutel niet meer dan één keer gebruiken, noch kunt u dezelfde waarde aan verschillende leden toekennen. Op deze manier helpt het dubbele waarden voor meerdere opsommingsleden te voorkomen.
De partial
decorateur is een krachtig hulpmiddel dat wordt gebruikt om deelfuncties te creëren. Met gedeeltelijke functies kunt u enkele argumenten van de oorspronkelijke functie vooraf instellen en een nieuwe functie genereren met die argumenten al ingevuld.
Voorbeeld:
from functools import partial
# Original function
def power(base, exponent):
return base ** exponent
# Creating a partial function with the exponent fixed to 2
square = partial(power, exponent=2)
# Using the partial function
result = square(3)
print("Output:",result)
Output:
In de bovenstaande implementatie hebben we een functie “macht” die twee argumenten “basis” en “exponent” accepteert en het resultaat retourneert van het grondtal verheven tot de macht van exponent. We hebben een gedeeltelijke functie gemaakt met de naam “vierkant” met behulp van de originele functie waarin de exponent vooraf is ingesteld op 2. Op deze manier kunnen we de functionaliteit van originele functies uitbreiden met behulp van een partial
decorateur.
De @singledisptach
decorateur wordt gebruikt om generieke functies te creëren. Hiermee kunt u verschillende implementaties definiëren van functies met dezelfde naam maar met verschillende argumenttypen. Dit is met name handig als u wilt dat uw code zich anders gedraagt voor verschillende gegevenstypen.
Voorbeeld:
from functools import singledispatch
# Decorator
@singledispatch
def display_info(arg):
print(f"Generic: {arg}")
# Registering specialized implementations for different types
@display_info.register(int)
def display_int(arg):
print(f"Received an integer: {arg}")
@display_info.register(float)
def display_float(arg):
print(f"Received a float: {arg}")
@display_info.register(str)
def display_str(arg):
print(f"Received a string: {arg}")
@display_info.register(list)
def display_sequence(arg):
print(f"Received a sequence: {arg}")
# Using the generic function with different types
display_info(39)
display_info(3.19)
display_info("Hello World!")
display_info([2, 4, 6])
Output:
Received an integer: 39
Received a float: 3.19
Received a string: Hello World!
Received a sequence: [2, 4, 6]
In de bovenstaande implementatie hebben we eerst de generieke functie ontwikkeld display_info()
met de @singledisptach
decorateur en registreerde vervolgens de implementatie ervan voor int, float, string en list afzonderlijk. De uitvoer toont de werking van display_info()
voor afzonderlijke gegevenstypen.
De @classmethod
is een decorateur die wordt gebruikt om klassenmethoden binnen de klasse te definiëren. Klassemethoden zijn gebonden aan de klasse en niet aan het object van de klasse. Het belangrijkste onderscheid tussen statische methoden en klassenmethoden ligt in hun interactie met de klassenstaat. Klassenmethoden hebben toegang tot de klassenstatus en kunnen deze wijzigen, terwijl statische methoden geen toegang hebben tot de klassenstatus en onafhankelijk werken.
Voorbeeld:
class Student:
total_students = 0
def __init__(self, name, age):
self.name = name
self.age = age
Student.total_students += 1
@classmethod
def increment_total_students(cls):
cls.total_students += 1
print(f"Class method called. Total students now: {cls.total_students}")
# Creating instances of the class
student1 = Student(name="Tom", age=20)
student2 = Student(name="Cruise", age=22)
# Calling the class method
Student.increment_total_students() #Total students now: 3
# Accessing the class variable
print(f"Total students from student 1: {student1.total_students}")
print(f"Total students from student 2: {student2.total_students}")
Output:
Class method called. Total students now: 3
Total students from student 1: 3
Total students from student 2: 3
In de bovenstaande implementatie is de Student klasse heeft totaal_studenten als klassevariabele. De @classmethod
decorateur wordt gebruikt om de increment_total_students()
class-methode om de totaal_studenten variabel. Telkens wanneer we een exemplaar van de klasse Student maken, wordt het totale aantal studenten met één verhoogd. We hebben twee exemplaren van de klasse gemaakt en vervolgens de class-methode gebruikt om de totaal_studenten variabel naar 3, wat ook wordt weerspiegeld door de instanties van de klasse.
De @staticmethod
decorateur wordt gebruikt om statische methoden binnen een klasse te definiëren. Statische methoden zijn de methoden die kunnen worden aangeroepen zonder een instantie van de klasse te maken. Statische methoden worden vaak gebruikt als ze geen toegang hebben tot objectgerelateerde parameters en meer gerelateerd zijn aan de klasse als geheel.
Voorbeeld:
class MathOperations:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def subtract(x, y):
return x - y
# Using the static methods without creating an instance of the class
sum_result = MathOperations.add(5, 4)
difference_result = MathOperations.subtract(8, 3)
print("Sum:", sum_result)
print("Difference:", difference_result)
Output:
Sum: 9
Difference: 5
In de bovenstaande implementatie hebben we gebruikt @staticmethod
om een statische methode add() te definiëren voor de klasse “MathOperations”. We hebben de twee cijfers “4” en “5” toegevoegd, wat resulteert in “9” zonder dat er een instantie van de klasse is gemaakt. Trek op dezelfde manier de twee getallen “8” en “3” af om “5” te krijgen. Op deze manier kunnen statische methoden worden gegenereerd om hulpprogrammafuncties uit te voeren waarvoor de status van een instantie niet vereist is.
De @property
decorateur wordt gebruikt om de gettermethoden voor het klasse-attribuut te definiëren. De gettermethoden zijn de methoden die de waarde van een attribuut retourneren. Deze methoden worden gebruikt voor gegevensinkapseling, die specificeert wie toegang heeft tot de details van de klasse of instantie.
Voorbeeld:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
# Getter method for the radius.
return self._radius
@property
def area(self):
# Getter method for the area.
return 3.14 * self._radius**2
# Creating an instance of the Circle class
my_circle = Circle(radius=5)
# Accessing properties using the @property decorator
print("Radius:", my_circle.radius)
print("Area:", my_circle.area)
Output:
Radius: 5
Area: 78.5
In de bovenstaande implementatie heeft de klasse “Cirkel” een attribuut “radius”. We hebben gebruikt @property
om de gettermethoden voor zowel de straal als de oppervlakte in te stellen. Het biedt een schone en consistente interface voor de gebruikers van de klasse om toegang te krijgen tot deze attributen.
In dit artikel worden enkele van de meest veelzijdige en functionele decorateurs belicht die u kunt gebruiken om uw code flexibeler en leesbaarder te maken. Met deze decorateurs kunt u de functionaliteiten van de oorspronkelijke functie uitbreiden om deze overzichtelijker en minder foutgevoelig te maken. Het zijn als magische accenten die ervoor zorgen dat je Python-programma's er netjes uitzien en soepel werken.
Kanwal Mehreen is een aspirant-softwareontwikkelaar met een grote interesse in datawetenschap en toepassingen van AI in de geneeskunde. Kanwal werd geselecteerd als de Google Generation Scholar 2022 voor de APAC-regio. Kanwal deelt graag technische kennis door artikelen te schrijven over trending topics en heeft een passie voor het verbeteren van de vertegenwoordiging van vrouwen in de technische industrie.
- Door SEO aangedreven content en PR-distributie. Word vandaag nog versterkt.
- PlatoData.Network Verticale generatieve AI. Versterk jezelf. Toegang hier.
- PlatoAiStream. Web3-intelligentie. Kennis versterkt. Toegang hier.
- PlatoESG. carbon, CleanTech, Energie, Milieu, Zonne, Afvalbeheer. Toegang hier.
- Plato Gezondheid. Intelligentie op het gebied van biotech en klinische proeven. Toegang hier.
- Bron: https://www.kdnuggets.com/8-built-in-python-decorators-to-write-elegant-code?utm_source=rss&utm_medium=rss&utm_campaign=8-built-in-python-decorators-to-write-elegant-code