Dekorator python mendapatkan nama fungsi

Dekorator bisa menjadi topik yang menakutkan saat pertama kali ditemui. Sementara The Zen of Python menyatakan "Harus ada satu– dan sebaiknya hanya satu cara yang jelas untuk melakukannya", ada banyak cara yang sama validnya untuk mengimplementasikan dekorator yang sama. Metode yang berbeda ini dapat dikategorikan sebagai berbasis fungsi, berbasis kelas, atau campuran keduanya. Dalam posting ini saya akan menjelaskan desain dan perilaku dekorator Python dan memberikan contoh dekorator yang sering saya gunakan dalam kode saya sendiri

Apa itu Dekorator?

Dalam Python, semuanya benar-benar objek, termasuk fungsi. Karena fungsi adalah objek, mereka dapat diteruskan sebagai argumen ke fungsi lain, mereka dapat menjadi nilai balik dari suatu fungsi, dan mereka dapat ditugaskan ke variabel. Jika Anda memahami konsep-konsep ini maka Anda memiliki semua yang Anda butuhkan untuk memahami dekorator

Dekorator adalah objek yang dapat dipanggil yang mengambil fungsi sebagai parameter input. Saya secara khusus mengatakan "objek yang dapat dipanggil" daripada "fungsi" karena Python memungkinkan Anda membuat jenis objek yang dapat dipanggil lainnya. Fitur bahasa yang menarik inilah yang memungkinkan kita membuat dekorator berbasis kelas, seperti yang akan kita lihat sebentar lagi

Dekorator Sederhana

Dekorator adalah pembungkus yang memungkinkan Anda mengeksekusi kode sebelum dan sesudah fungsi "dibungkus" (atau "dihiasi") dijalankan. Dengan membuat fungsi dekorator secara manual, efek "pembungkus" ini dapat dengan mudah didemonstrasikan. Pertimbangkan modul

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
6 yang diberikan di bawah ini

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

  • Baris 2.

    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    7 menerima fungsi sebagai parameter, membuatnya menjadi dekorator

  • Baris 3.

    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    8 (didefinisikan dalam
    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    7) memungkinkan kita untuk mengeksekusi kode sebelum dan sesudah menjalankan fungsi yang dibungkus

  • Baris 5. Pernyataan cetak ini akan dijalankan sebelum fungsi yang dibungkus.

  • Baris 6. Fungsi yang dibungkus dijalankan dalam

    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    8

  • Baris 7. Pernyataan cetak ini akan dijalankan setelah fungsi yang dibungkus

  • Baris 9. Ini mungkin bagian yang paling membingungkan.

    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    8 adalah nilai kembalian dari fungsi dekorator (
    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    7). Pada titik ini, fungsi yang dibungkus (
    >>> undecorated_function = simple_decorator(undecorated_function)
    >>> undecorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    _3) BELUM telah dieksekusi.

  • Baris 12. Kami akan menggunakan fungsi ini untuk menunjukkan cara kerja

    >>> decorated_function()
    Preparing to execute: undecorated_function
    I FORBID you from modifying how this function behaves!
    Finished executing: undecorated_function
    7

Buka shell Python interaktif dan jalankan

>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5 untuk melihat perilaku sebelum menerapkan dekorator apa pun. Selanjutnya, kami meneruskan
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
_6 sebagai parameter ke
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
7, dan menyimpan nilai yang dikembalikan di
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
8

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)

Harap perhatikan perbedaan antara memanggil fungsi (

>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5) dan meneruskan fungsi sebagai parameter ke fungsi lain (
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
0). Jika kita telah mengeksekusi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
_1, kita tidak akan melihat efek dari fungsi wrapper. Perilakunya akan sama seperti saat kita mengeksekusi
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5

Terakhir, kami mengeksekusi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
3

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function

Ini adalah hasil yang kami harapkan setelah menerapkan

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
7. Namun, bukankah lebih baik jika kita dapat mengubah perilaku ________9______6 secara permanen?

>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
_

Inilah yang terjadi ketika Anda mendekorasi fungsi menggunakan sintaks

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
8 Python. Untuk memperkuat poin ini, kita dapat memodifikasi kode kita untuk menggunakan sintaks dekorator normal. Perhatikan bahwa kami menerapkan dekorator ke
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
6 di Baris 12

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

Mari kita verifikasi bahwa perilaku fungsi telah dimodifikasi

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function

Seperti yang Anda lihat,

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_0 hanyalah gula sintaksis untuk
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

1

Jenis dekorator ini bagus, tetapi bagaimana jika fungsi asli kita memiliki satu atau lebih parameter masukan? . Apa yang dapat kita lakukan untuk memperbaikinya?

Meneruskan Argumen ke Fungsi Terbungkus

Memperbaiki ini sangat mudah. Ingat, saat kita menjalankan fungsi "dibungkus", kita benar-benar menjalankan fungsi yang dikembalikan oleh fungsi dekorator (

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
8 pada contoh sebelumnya). Nilai apa pun yang kami berikan ke fungsi ini dapat diteruskan ke fungsi yang dibungkus

Namun, kami perlu mengakomodasi semua kemungkinan kombinasi parameter masukan. Kita dapat melakukan ini dengan memodifikasi

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
_8 untuk menerima
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

5 dan meneruskannya ke
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
3. Ini telah diimplementasikan dalam modul baru, ________30______7

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
"""decorators.better"""
def a_better_decorator(function_to_decorate):
    def function_wrapper(*args, **kwargs):

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate(*args, **kwargs)
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@a_better_decorator
def greeting_anonymous():
    print("Hello anonymous website viewer!")


@a_better_decorator
def greeting_personal(name="Aaron"):
    print(f"Hello {name}!")

Mari kita uji versi ini dengan dua fungsi yang dihias,

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

8 dan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

9

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

0

Ini berfungsi persis seperti yang kita butuhkan, nilai yang kita berikan ke

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

9 digunakan karena itu diteruskan dari
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
8 ke
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
3. Selain itu, kami tidak merusak fungsionalitas yang ada karena fungsi yang tidak menggunakan parameter input apa pun (
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

8) juga didekorasi dan berfungsi seperti yang diharapkan

Meneruskan Argumen ke Dekorator

Dekorator yang telah kita buat sejauh ini tentu saja berguna untuk berbagai skenario, tetapi mereka juga terbatas karena tidak ada cara untuk menyampaikan argumen kepada dekorator itu sendiri. Apa bedanya dengan dekorator terakhir yang kita buat?

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

1

Jika Anda ingat kembali ke awal posting ini, saya menyebutkan bahwa, secara umum, ada dua cara berbeda untuk mengimplementasikan dekorator Python. berbasis fungsi dan berbasis kelas. Contoh yang telah kita lihat sejauh ini semuanya berbasis fungsi. Kecuali jika Anda perlu membuat dekorator yang menerima argumen, Anda harus menggunakan desain berbasis fungsi ini karena lebih mudah dibaca dan membutuhkan lebih sedikit sarang/lekukan daripada desain berbasis kelas yang setara.

Namun, saat Anda perlu meneruskan argumen ke dekorator, tidak ada keuntungan menggunakan desain berbasis fungsi atau berbasis kelas. Mari kita lihat desain berbasis fungsi terlebih dahulu karena ini merupakan perkembangan alami dari dekorator yang telah kita periksa

Desain Berbasis Fungsi

Bentuk generik dekorator berbasis fungsi yang menerima argumen diberikan di bawah ini

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

2
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

3

Untuk meneruskan argumen ke dekorator, kami menambahkan fungsi pembungkus lain, yang disebut

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
4 (Baris 2). Saya menyebutnya pabrik karena nilai pengembalian adalah dekorator fungsi aktual (
(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5 adalah tempat
>>> undecorated_function = simple_decorator(undecorated_function)
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
3 diteruskan sebagai argumen)

Untuk memahami cara kerjanya, Anda perlu menyadari bahwa Baris 15 (tempat kita menerapkan dekorator ke suatu fungsi) sebenarnya adalah .

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5 adalah dekorator sebenarnya tetapi untuk meneruskan params "foo" dan "bar" ke dekorator, kami harus memanggil metode pabrik yang membuat dekorator aktual yang menerima fungsi
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
0 sebagai argumen dan membungkusnya.

Bandingkan ini dengan dekorator lain yang telah kita buat. ketika suatu fungsi didekorasi dengan

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@simple_decorator
def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

0 atau
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
2 ini bukan pemanggilan fungsi (perhatikan bahwa tidak ada tanda kurung setelah nama dekorator).

Mari jalankan REPL dan uji dekorator ini. Kami juga akan memverifikasi bahwa kami masih dapat menggunakan fungsi yang didekorasi seperti yang diharapkan dengan meneruskan argumen yang mengubah perilakunya

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_4

Seperti yang Anda lihat, argumen yang diteruskan ke dekorator (

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
3 dan
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
4) digunakan oleh fungsi pembungkus, dan nilai yang diteruskan ke fungsi yang didekorasi (
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
5/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
6) juga digunakan saat fungsi pembungkus dijalankan

Fungsi, Kelas, dan Callable

Apakah Anda akrab dengan? .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
_9 jika objek yang diberikan tampaknya dapat dipanggil dan
"""decorators.better"""
def a_better_decorator(function_to_decorate):
    def function_wrapper(*args, **kwargs):

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate(*args, **kwargs)
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@a_better_decorator
def greeting_anonymous():
    print("Hello anonymous website viewer!")


@a_better_decorator
def greeting_personal(name="Aaron"):
    print(f"Hello {name}!")

0 jika tidak. Jika menurut Anda fungsi adalah satu-satunya "yang dapat dipanggil" yang ada, Anda mungkin menganggap fungsi ini agak tidak berguna atau tidak perlu. Namun, kelas juga dapat dipanggil karena ini adalah cara pembuatan instance baru (mis. g. ,
"""decorators.better"""
def a_better_decorator(function_to_decorate):
    def function_wrapper(*args, **kwargs):

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate(*args, **kwargs)
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@a_better_decorator
def greeting_anonymous():
    print("Hello anonymous website viewer!")


@a_better_decorator
def greeting_personal(name="Aaron"):
    print(f"Hello {name}!")

_1)

Sintaks panggilan,

"""decorators.better"""
def a_better_decorator(function_to_decorate):
    def function_wrapper(*args, **kwargs):

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate(*args, **kwargs)
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@a_better_decorator
def greeting_anonymous():
    print("Hello anonymous website viewer!")


@a_better_decorator
def greeting_personal(name="Aaron"):
    print(f"Hello {name}!")

2, dapat memanggil fungsi atau membuat instance kelas seperti yang baru saja kita lihat. Tetapi Python memiliki fitur unik yang juga dapat memanggil objek selain fungsi. Menambahkan metode
"""decorators.better"""
def a_better_decorator(function_to_decorate):
    def function_wrapper(*args, **kwargs):

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate(*args, **kwargs)
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@a_better_decorator
def greeting_anonymous():
    print("Hello anonymous website viewer!")


@a_better_decorator
def greeting_personal(name="Aaron"):
    print(f"Hello {name}!")

_3 ke kelas apa pun akan membuat instance dari kelas tersebut dapat dipanggil. Ini memungkinkan kita membuat dekorator yang diimplementasikan menggunakan kelas

Desain Berbasis Kelas

Dekorator yang sama dapat diimplementasikan menggunakan instance kelas yang dapat dipanggil

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_6

Perbedaan utama antara desain berbasis fungsi dan berbasis kelas adalah bagaimana argumen yang diteruskan ke dekorator ditangani. Dalam pendekatan berbasis fungsi, argumen tersedia untuk

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
8 sebagai variabel lokal. Dalam desain berbasis kelas, argumen diberikan ke metode
"""decorators.better"""
def a_better_decorator(function_to_decorate):
    def function_wrapper(*args, **kwargs):

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate(*args, **kwargs)
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


@a_better_decorator
def greeting_anonymous():
    print("Hello anonymous website viewer!")


@a_better_decorator
def greeting_personal(name="Aaron"):
    print(f"Hello {name}!")

5 dan ditugaskan ke variabel instan yang dapat diakses dari
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
8

Kami dapat memastikan bahwa dekorator ini berperilaku persis sama dengan versi berbasis fungsi

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

7

Desain Mana yang Lebih Baik?

Apakah ada keuntungan menggunakan salah satu desain dekorator? . Namun, saya mengakui bahwa desain berbasis fungsi lebih konvensional karena gagasan objek yang dapat dipanggil yang merupakan turunan dari kelas (bukan fungsi) bukanlah yang diharapkan kebanyakan orang ketika mereka menemukan konsep dekorator.

Selain itu, tidak ada manfaat yang jelas untuk memilih satu desain dari yang lain. Anda harus menggunakan desain yang paling masuk akal bagi Anda

Selalu Gunakan >>> decorated_function() Preparing to execute: undecorated_function I FORBID you from modifying how this function behaves! Finished executing: undecorated_function5

Saya sengaja meninggalkan sesuatu yang sangat penting dari contoh dekorator ini. Anda harus SELALU menghias

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
8 (atau nama apa pun yang digunakan dalam aplikasi Anda) dengan dekorator
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5 (terletak di modul
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

00 pustaka standar). Mengapa ini penting?

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_8

Saat kami memeriksa nama dan tanda tangan fungsi

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
0, kami malah menerima nama dan tanda tangan dekorator yang diterapkan padanya. Meskipun membingungkan, akan lebih memusingkan jika Anda perlu men-debug kode ini. Ini mudah diperbaiki dengan dekorator
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
_5 (Baris 2,11)

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

9
(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
0

Sekarang, jika kita memeriksa

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
_0 kita akan melihat nama dan tanda tangan yang benar

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
1

Mengapa saya tidak menyertakan dekorator

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
5 pada contoh sebelumnya?

Mudah-mudahan Anda memiliki pemahaman yang lebih baik tentang bagaimana dekorator dirancang dan bagaimana perilakunya di Python. Sisa dari posting ini akan berisi contoh dekorator yang sering saya gunakan dalam proyek Python saya bersama dengan fungsi pytest yang menunjukkan penggunaan yang dimaksud

Contoh. Batas Waktu Fungsi

Jika Anda pernah menulis kode yang berinteraksi dengan layanan luar, Anda mungkin pernah mengalami situasi di mana program Anda terhenti menunggu respons tanpa ada cara untuk membatalkan pemanggilan fungsi. Salah satu cara untuk melepaskan diri adalah dengan dekorator

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

05

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
2
(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
3

Sintaks yang digunakan pada Baris 6 di atas mencegah pengguna menentukan argumen posisional dengan dekorator

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

05. Hal ini dilakukan untuk memastikan bahwa tujuan dekorator jelas bagi pembaca berdasarkan penggunaannya. Tanpa tanda bintang (
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_07) dalam definisi fungsi, pengguna dapat menghias fungsi dengan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

08, bukan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

09. Penggunaan terakhir mengkomunikasikan arti dari nilai
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

10 dalam konteks dekorator
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

05. Jika Anda tidak terbiasa dengan sintaks ini, Anda dapat menemukan latar belakang dan pembenaran untuk fitur ini di PEP 3102

Sangat mudah digunakan. Cukup hiasi fungsi apa saja dengan

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

12 dan tentukan jumlah detik untuk menunggu sebelum membatalkan pemanggilan fungsi seperti yang ditunjukkan di bawah ini (Baris 7). Jika fungsi selesai sebelum jumlah detik yang ditentukan berlalu, program Anda akan terus dijalankan. Namun jika fungsi belum selesai setelah jumlah detik yang ditentukan berlalu,
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

13 akan dimunculkan, membatalkan panggilan fungsi

Dalam skenario pengujian sederhana di bawah ini, fungsi

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_14 menunggu selama dua detik saat dipanggil. Karena dihiasi dengan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

15 a
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

13 akan dinaikkan satu detik setelah disebut. Fungsi
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_17 memverifikasi bahwa kesalahan yang benar dimunculkan (Baris 13-14)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
5

Contoh. Coba Ulang Fungsi

Contoh berikutnya mirip dengan dekorator

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_05 karena keduanya dirancang untuk menangani fungsi yang tidak dapat diandalkan. Dekorator
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_19 menambahkan logika coba lagi ke fungsi yang didekorasi

Untuk menggunakannya, Anda menentukan satu set

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

20 yang dapat memicu percobaan yang gagal, jumlah percobaan yang gagal yang dapat terjadi sebelum membatalkan panggilan fungsi (
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

21), jumlah detik penundaan setelah setiap percobaan yang gagal sebelum mencoba lagi (
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

22)

Definisi dekorator sebenarnya dimulai pada Baris 26 di bawah. Sebelum itu, Pengecualian khusus

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_23 didefinisikan (Baris 6-13). Ini adalah pengecualian yang muncul setelah
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_21 untuk memanggil fungsi telah gagal. Fungsi
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_25 (Baris 16-23) diberikan sebagai contoh dari apa yang dapat disediakan untuk parameter
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

19 dekorator
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

27

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
6
(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
7

Kita dapat menggunakan dekorator

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_05 untuk mendemonstrasikan dan menguji dekorator
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

19. Karena kita perlu mengetahui jenis
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_30 yang kita harapkan terjadi saat kita memanggil fungsi yang dihias, kita tentukan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

31 karena ini adalah kesalahan yang diangkat oleh dekorator
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

05

Dengan kode di bawah ini, kami akan mencoba memanggil

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

33 maksimal dua kali. Karena satu-satunya hal yang dilakukan fungsi ini adalah menunggu selama dua detik dan kita telah menghiasinya dengan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

15, memanggilnya akan selalu memunculkan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

13. Oleh karena itu, setelah upaya kedua yang gagal, dekorator
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_19 akan menaikkan
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

23

Akhirnya, fungsi

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_38 memverifikasi bahwa
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

23 sebenarnya dimunculkan setelah memanggil fungsi
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

33

(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
8
(venv) decorators $ python
Python 3.7.6 (default, Jan 19 2020, 06:08:58)
[Clang 11.0.0 (clang-1100.0.33.8)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from decorators.basic import * 
>>> undecorated_function()
I FORBID you from modifying how this function behaves!
>>> decorated_function = simple_decorator(undecorated_function)
9

Contoh. Log Tanda Tangan Panggilan dan Waktu Eksekusi

Aplikasi dekorator yang paling umum mungkin adalah logging. Sangat mudah untuk mengetahui alasannya, memiliki kemampuan untuk menjalankan kode segera sebelum dan setelah suatu fungsi dipanggil memungkinkan Anda untuk melaporkan informasi dan menangkap metrik

Dekorator ini menggunakan desain berbasis kelas, dan memungkinkan pengguna menyediakan logger khusus. Jika tidak ada yang tersedia, logger akan dibuat berdasarkan modul yang berisi fungsi yang dibungkus

Setiap kali fungsi dipanggil, dekorator

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_41 menambahkan entri level
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

42 ke log dengan data berikut

  • Stempel waktu saat fungsi dipanggil
  • nama fungsi dan nilai semua argumen yang diberikan ke fungsi (mis. e. tanda panggilan)
  • Waktu berlalu saat menjalankan fungsi

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
0
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
1

Kode di bawah menguji dekorator

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

_41 dengan logger khusus dan dengan logger default. Dengan logger default, kami mengharapkan nama logger menjadi nama modul yang berisi fungsi yang didekorasi,
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

44 (Baris 30). Saat logger khusus disediakan, kami berharap namanya cocok dengan nilai yang kami tentukan saat logger dibuat,
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

45 (Baris 10, 38)

Fitur yang bagus dari dekorator ini adalah tanda tangan panggilan fungsi berisi nama dan nilai dari semua argumen kata kunci, bahkan jika nilai default digunakan atau jika nama tidak diberikan saat panggilan terjadi. Misalnya, panggilan ke fungsi yang dihias pada Baris 28 adalah

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

46, tetapi tanda panggilan yang dicatat berisi nama ketiga argumen,
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

47 (Baris 32)

Demikian pula, panggilan ke fungsi yang dihias di Baris 36 adalah

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

48, yang hanya menyediakan dua argumen. Tanda panggilan yang dicatat termasuk nilai default dari argumen yang hilang,
"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

49 (Baris 40)

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
2
>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
3

Jika kita menjalankan

"""decorators.basic"""
def simple_decorator(function_to_decorate):
    def function_wrapper():

        print(f"Preparing to execute: {function_to_decorate.__name__}")
        function_to_decorate()
        print(f"Finished executing: {function_to_decorate.__name__}")

    return function_wrapper


def undecorated_function():
    print("I FORBID you from modifying how this function behaves!")

50 untuk contoh dekorator ini, semua tes lulus

>>> decorated_function()
Preparing to execute: undecorated_function
I FORBID you from modifying how this function behaves!
Finished executing: undecorated_function
_4

Ringkasan

Jika Anda ingin mengunduh semua atau sebagian kode dari pos ini, Anda dapat dengan mudah melakukannya dari intisari Github yang ditautkan di bawah ini

Dekorator Python

Saya harap pengantar dekorator dengan Python ini membantu dan mudah dimengerti. Jika ada pertanyaan, kritik atau masukan silahkan tinggalkan komentar. terima kasih

Bagaimana Anda mencetak nama fungsi dengan Python?

Metode 1. Dapatkan Nama Fungsi dengan Python menggunakan function. nama_fungsi . Dengan menggunakan fungsi properti fungsi sederhana, func_name, seseorang bisa mendapatkan nama fungsi dan karenanya bisa sangat berguna untuk tujuan Pengujian dan juga untuk dokumentasi di waktu-waktu tertentu. Kekurangannya adalah ini hanya berfungsi untuk Python2.

Bagaimana Anda memanggil fungsi di dekorator?

call() dekorator dengan Python . Dekorator memungkinkan program dimodifikasi untuk menambahkan kode apa pun yang memiliki peran khusus untuk dimainkan. Dekorator dipanggil sebelum definisi fungsi yang telah Anda dekorasi. def dekorasi(fungsi).

Apa fungsi dekorator di Python?

Dekorator adalah pola desain dalam Python yang memungkinkan pengguna menambahkan fungsionalitas baru ke objek yang sudah ada tanpa mengubah strukturnya . Dekorator biasanya dipanggil sebelum definisi fungsi yang ingin Anda hias.

Bagaimana cara menemukan nama string dalam suatu fungsi?

Anda bisa mendapatkan nama fungsi sebagai string dengan menggunakan variabel __name__ khusus .