Decorators in Python

Decorators in Python

דקורטורים הם כלי רב עוצמה ושימושי בPython  מכיוון שהוא מאפשר למתכנתים לשנות את ההתנהגות של פונקציה או מחלקה. דקורטורים מאפשרים לנו לעטוף פונקציה נוספת על מנת להרחיב את התנהגות הפונקציה העטופה, מבלי לשנות אותה לצמיתות. אבל לפני שנצלול עמוק לתוך הנושא בואו נבין כמה מושגים שיועילו בלימוד הנושא.

אובייקט מחלקה ראשונה

ב-Python, פונקציות הן אובייקטים מהשורה הראשונה, מה שאומר שניתן להשתמש בפונקציות ב-Python או להעביר אותן כארגומנטים.

מאפיינים של פונקציות מחלקה ראשונה:

פונקציה היא מופע מסוג אובייקט.

אתה יכול לאחסן את הפונקציה במשתנה.

ניתן להעביר את הפונקציה כפרמטר לפונקציה אחרת.

אתה יכול להחזיר את הפונקציה מפונקציה.

אתה יכול לאחסן אותם במבני נתונים כגון טבלאות, רשימות, …

בדוק את הדוגמאות שלהלן להבנה טובה יותר…

# Python program to illustrate functions

# can be treated as objects

def shout(text):

    return text.upper()

 

print(shout('Hello'))

 

yell = shout

 

print(yell('Hello'))

 

Output:

HELLO

HELLO

בדוגמה לעיל, הקצינו את הפונקציה shout למשתנה. זה לא יקרא לפונקציה במקום זאת, הוא לוקח את אובייקט הפונקציה שאליו מתייחסים צעקה ויוצר שם שני שמצביע עליו

.

# Python program to illustrate functions

# can be passed as arguments to other functions

def shout(text):

    return text.upper()

 

def whisper(text):

    return text.lower()

 

def greet(func):

    # storing the function in a variable

    greeting = func("""Hi, I am created by a function passed as an argument.""")

    print (greeting)

 

greet(shout)

greet(whisper)

Output:

HI, I AM CREATED BY A FUNCTION PASSED AS AN ARGUMENT.

hi, i am created by a function passed as an argument.

בדוגמה שלמעלה, פונקציית הברכה לוקחת פונקציה נוספת כפרמטר (צעקה ולחש במקרה זה). הפונקציה שהועברה כארגומנט נקראת אז בתוך הפונקציה greet.

דוגמה 3: החזרת פונקציות מפונקציה אחרת.

# Python program to illustrate functions

# Functions can return another function

 

def create_adder(x):

    def adder(y):

        return x+y

 

    return adder

 

add_15 = create_adder(15)

 

print(add_15(10))

 

Output:

25

בדוגמה שלמעלה, יצרנו פונקציה בתוך פונקציה אחרת ולאחר מכן החזרנו את הפונקציה שנוצרה בפנים.

שלוש הדוגמאות לעיל מתארות את המושגים החשובים הדרושים להבנת הנושא. לאחר שעברנו עליהם, תנו לנו עכשיו לצלול עמוק לתוך הנושא העיקרי ד.

 

מעצבים

כפי שצוין לעיל, המעצבים משמשים כדי לשנות את התנהגות הפונקציה או המעמד. ב-Decorators, פונקציות נלקחות כארגומנט לפונקציה אחרת ולאחר מכן נקראות בתוך פונקציית העטיפה.

 

תחביר עבור דקורטורים:

כפי שצוין לעיל, הדקורטורים משמשים כדי לשנות את התנהגות הפונקציה או המעמד. ב-Decorators, פונקציות נלקחות כארגומנט לפונקציה אחרת ולאחר מכן נקראות בתוך פונקציית העטיפה.

דקורטורים : 

@gfg_decorator

def hello_decorator():

    print("Gfg")

"'Above code is equivalent to –

def hello_decorator():

    print("Gfg")    

hello_decorator = gfg_decorator(hello_decorator)"'

 

בקוד שלמעלה, gfg_decorator היא פונקציה הניתנת להתקשרות, שתוסיף קוד כלשהו בחלק העליון של פונקציה נוספת, פונקציית hello_decorator ותחזיר את פונקציית ה-wrapper.

דקורטור יכול לשנות את ההתנהגות:

# defining a decorator

def hello_decorator(func):

 

    # inner1 is a Wrapper function in

    # which the argument is called

     

    # inner function can access the outer local

    # functions like in this case "func"

    def inner1():

        print("Hello, this is before function execution")

 

        # calling the actual function now

        # inside the wrapper function.

        func()

 

        print("This is after function execution")

         

    return inner1

 

 

# defining a function, to be called inside wrapper

def function_to_be_used():

    print("This is inside the function !!")

 

 

# passing 'function_to_be_used' inside the

# decorator to control its behaviour

function_to_be_used = hello_decorator(function_to_be_used)

 

 

# calling the function

function_to_be_used()

 

Output: 

Hello, this is before function execution

This is inside the function !!

This is after function execution

בואו נראה את ההתנהגות של הקוד לעיל וכיצד הוא פועל שלב אחר שלב כאשר קוראים ל-"function_to_beused".

בואו נקפוץ לדוגמא נוספת שבה נוכל לגלות בקלות את זמן הביצוע של פונקציה באמצעות דקורטור.

בעוד דוגמאות קוד נעמיק ב קורס Python

# importing libraries

import time

import math

 

# decorator to calculate duration

# taken by any function.

def calculate_time(func):

     

    # added arguments inside the inner1,

    # if function takes any arguments,

    # can be added like this.

    def inner1(*args, **kwargs):

 

        # storing time before function execution

        begin = time.time()

         

        func(*args, **kwargs)

 

        # storing time after function execution

        end = time.time()

        print("Total time taken in : ", func.__name__, end begin)

 

    return inner1

 

 

 

# this can be added to any function present,

# in this case to calculate a factorial

@calculate_time

def factorial(num):

 

    # sleep 2 seconds because it takes very less time

    # so that you can see the actual difference

    time.sleep(2)

    print(math.factorial(num))

 

# calling the function.

factorial(10)

 

Output: 

3628800

Total time taken in :  factorial 2.0061802864074707

 

מה אם פונקציה מחזירה משהו או ארגומנט מועבר לפונקציה?

בכל הדוגמאות לעיל הפונקציות לא החזירו כלום אז לא הייתה בעיה, אבל ייתכן שצריך את הערך המוחזר.

def hello_decorator(func):

    def inner1(*args, **kwargs):

         

        print("before Execution")

         

        # getting the returned value

        returned_value = func(*args, **kwargs)

        print("after Execution")

         

        # returning the value to the original frame

        return returned_value

         

    return inner1

 

 

# adding decorator to the function

@hello_decorator

def sum_two_numbers(a, b):

    print("Inside the function")

    return a + b

 

a, b = 1, 2

 

# getting the value through return of the function

print("Sum =", sum_two_numbers(a, b))

 

Output: 

before Execution

Inside the function

after Execution

Sum = 3

בדוגמה לעיל, ייתכן שתבחין בהבדל חד בפרמטרים של הפונקציה הפנימית. הפונקציה הפנימית לוקחת את הארגומנט בתור *args ו-**kwargs מה שאומר שניתן להעביר טופלה של ארגומנטים או מילון של ארגומנטים של מילות מפתח בכל אורך. זה הופך אותו למעצב כללי שיכול לקשט פונקציה עם כל מספר של ארגומנטים

 

שרשור של דקורטורים:

במונחים פשוטים יותר שרשור מעצבים פירושו לקשט פונקציה עם מספר דקורטורים..

דוגמא:

# code for testing decorator chaining

def decor1(func):

    def inner():

        x = func()

        return x * x

    return inner

 

def decor(func):

    def inner():

        x = func()

        return 2 * x

    return inner

 

@decor1

@decor

def num():

    return 10

 

print(num())

 

Output:

400

 

הדוגמה שלמעלה דומה לקריאת הפונקציה –

decor1(decor(num))

 

העתיד שלך בהייטק מתחיל כאן
צור איתי קשר עוד היום

דילוג לתוכן