Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Python

Python-decorateurs

Python-decorateurs

Een decorateur neemt een functie over, voegt wat functionaliteit toe en geeft deze terug. In deze tutorial leer je hoe je een decorateur kunt maken en waarom je deze zou moeten gebruiken.

Video:@Decorators in Python

Decorateurs in Python

Python heeft een interessante functie genaamd decorators om functionaliteit toe te voegen aan een bestaande code.

Dit wordt ook wel metaprogrammering genoemd omdat een deel van het programma een ander deel van het programma probeert te wijzigen tijdens het compileren.


Vereisten voor het leren van decorateurs

Om te begrijpen wat decorateurs zijn, moeten we eerst een paar basisdingen in Python weten.

We moeten ons comfortabel voelen met het feit dat alles in Python (Ja! Zelfs klassen), objecten zijn. Namen die we definiëren zijn eenvoudig identifiers die aan deze objecten zijn gebonden. Functies zijn geen uitzonderingen, het zijn ook objecten (met attributen). Er kunnen verschillende namen aan hetzelfde functieobject worden gebonden.

Hier is een voorbeeld.

def first(msg):
    print(msg)


first("Hello")

second = first
second("Hello")

Uitvoer

Hello
Hello

Wanneer u de code uitvoert, werken beide functies first en second dezelfde output geven. Hier de namen first en second verwijzen naar hetzelfde functie-object.

Nu worden de dingen vreemder.

Functies kunnen als argumenten aan een andere functie worden doorgegeven.

Als je functies zoals map . hebt gebruikt , filter en reduce in Python, dan weet je dit al.

Dergelijke functies die andere functies als argumenten aannemen, worden ook wel functies van hogere orde . genoemd . Hier is een voorbeeld van zo'n functie.

def inc(x):
    return x + 1


def dec(x):
    return x - 1


def operate(func, x):
    result = func(x)
    return result

We roepen de functie als volgt aan.

>>> operate(inc,3)
4
>>> operate(dec,3)
2

Bovendien kan een functie een andere functie teruggeven.

def is_called():
    def is_returned():
        print("Hello")
    return is_returned


new = is_called()

# Outputs "Hello"
new()

Uitvoer

Hello

Hier, is_returned() is een geneste functie die wordt gedefinieerd en geretourneerd elke keer dat we is_called() . aanroepen .

Ten slotte moeten we meer weten over Closures in Python.


Terug naar Decorateurs

Functies en methoden worden aanroepbaar genoemd zoals ze genoemd kunnen worden.

In feite kan elk object dat de speciale __call__() . implementeert methode wordt callable genoemd. Dus in de meest basale zin is een decorateur een callable die een callable retourneert.

Kortom, een decorateur neemt een functie in zich, voegt wat functionaliteit toe en geeft deze terug.

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner


def ordinary():
    print("I am ordinary")

Wanneer u de volgende codes in shell uitvoert,

>>> ordinary()
I am ordinary

>>> # let's decorate this ordinary function
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

In het bovenstaande voorbeeld, make_pretty() is een binnenhuisarchitect. In de toewijzingsstap:

pretty = make_pretty(ordinary)

De functie ordinary() werd versierd en de geretourneerde functie kreeg de naam pretty .

We kunnen zien dat de decorateurfunctie een aantal nieuwe functionaliteit aan de oorspronkelijke functie heeft toegevoegd. Dit is vergelijkbaar met het inpakken van een cadeau. De decorateur fungeert als een wikkel. De aard van het object dat is versierd (eigenlijk geschenk binnenin) verandert niet. Maar nu ziet het er mooi uit (sinds het versierd is).

Over het algemeen decoreren we een functie en wijzen we deze opnieuw toe als,

ordinary = make_pretty(ordinary).

Dit is een veel voorkomende constructie en om deze reden heeft Python een syntaxis om dit te vereenvoudigen.

We kunnen de @ . gebruiken symbool samen met de naam van de decorateurfunctie en plaats deze boven de definitie van de te decoreren functie. Bijvoorbeeld,

@make_pretty
def ordinary():
    print("I am ordinary")

is gelijk aan

def ordinary():
    print("I am ordinary")
ordinary = make_pretty(ordinary)

Dit is slechts een syntactische suiker om decorateurs te implementeren.


Functies decoreren met parameters

De bovenstaande decorateur was eenvoudig en werkte alleen met functies die geen parameters hadden. Wat als we functies hadden die parameters innamen zoals:

def divide(a, b):
    return a/b

Deze functie heeft twee parameters, a en b . We weten dat het een foutmelding geeft als we b . doorgeven als 0.

>>> divide(2,5)
0.4
>>> divide(2,0)
Traceback (most recent call last):
...
ZeroDivisionError: division by zero

Laten we nu een decorateur maken om te controleren op dit geval dat de fout veroorzaakt.

def smart_divide(func):
    def inner(a, b):
        print("I am going to divide", a, "and", b)
        if b == 0:
            print("Whoops! cannot divide")
            return

        return func(a, b)
    return inner


@smart_divide
def divide(a, b):
    print(a/b)

Deze nieuwe implementatie retourneert None als de fout zich voordoet.

>>> divide(2,5)
I am going to divide 2 and 5
0.4

>>> divide(2,0)
I am going to divide 2 and 0
Whoops! cannot divide

Op deze manier kunnen we functies decoreren die parameters nodig hebben.

Een scherp waarnemer zal opmerken dat parameters van de geneste inner() functie binnen de decorateur is hetzelfde als de parameters van functies die hij decoreert. Hiermee rekening houdend, kunnen we nu algemene decorateurs maken die met een willekeurig aantal parameters werken.

In Python wordt deze magie gedaan als function(*args, **kwargs) . Op deze manier, args zal de tupel van positionele argumenten zijn en kwargs zal het woordenboek van trefwoordargumenten zijn. Een voorbeeld van zo'n decorateur is:

def works_for_all(func):
    def inner(*args, **kwargs):
        print("I can decorate any function")
        return func(*args, **kwargs)
    return inner

Decorateurs aaneenketenen in Python

Meerdere decorateurs kunnen in Python worden geketend.

Dit wil zeggen dat een functie meerdere keren kan worden ingericht met verschillende (of dezelfde) decorateurs. We plaatsen de decorateurs gewoon boven de gewenste functie.

def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner


def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner


@star
@percent
def printer(msg):
    print(msg)


printer("Hello")

Uitvoer

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

De bovenstaande syntaxis van,

@star
@percent
def printer(msg):
    print(msg)

is gelijk aan

def printer(msg):
    print(msg)
printer = star(percent(printer))

De volgorde waarin we decorateurs ketenen, is van belang. Als we de volgorde hadden omgedraaid als,

@percent
@star
def printer(msg):
    print(msg)

De uitvoer zou zijn:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Hello
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Python

  1. Python-gegevenstypen
  2. Python-operators
  3. Python pass-instructie
  4. Python-functieargumenten
  5. Python Anonieme/Lambda-functie
  6. Python Lambda-functies met VOORBEELDEN
  7. Python abs() Functie:Voorbeelden van absolute waarden
  8. Python round() functie met VOORBEELDEN
  9. Python range() Functie:Float, List, For loop Voorbeelden
  10. Python map() functie met VOORBEELDEN
  11. Opbrengst in Python-zelfstudie:voorbeeld van generator en rendement versus rendement