Rumah >pembangunan bahagian belakang >Tutorial Python >Melihat lebih dekat fungsi penghias Python

Melihat lebih dekat fungsi penghias Python

WBOY
WBOYke hadapan
2022-06-24 12:50:422028semak imbas

Artikel ini membawakan anda pengetahuan yang relevan tentang python terutamanya mengatur isu yang berkaitan dengan fungsi penghias, termasuk proses pembentukan, intipati dan fungsi, kemajuan dan pengoptimuman penghias , saya harap ia akan membantu semua orang.

Melihat lebih dekat fungsi penghias Python

Pembelajaran yang disyorkan: python

Jika saya menulis fungsi f

def f():
    print('hello')

maka saya mahu Mengetahui masa yang diperlukan untuk melaksanakan fungsi ini adalah mudah, saya hanya perlu menukar kod kepada yang berikut

import time
def f():
    start = time.time()   #获取程序执行开始的时间
    print('hello')
    end = time.time()     #获取程序执行结束的时间
    print(end - start)    #得出函数f执行所要时间

f()

Tetapi kemudian saya menulis banyak fungsi f2, f3...fn, dan saya ingin tahu. setiap satu Masa yang diperlukan untuk melaksanakan fungsi, bukankah sangat menjengkelkan jika kita mengubahnya seperti di atas? Masih tidak boleh, kerana ia akan menjadi terlalu banyak masalah. Apa yang perlu dilakukan? Jadi saya mempunyai idea dan menulis fungsi pemasa. . .

import time
def timer(func):
    start = time.time()
    func()
    print(time.time() - start)

def f():
    print('hello')


def f2():
    print('xorld')

timer(f)
timer(f2)

Bukankah ini kelihatan lebih mudah? Tidak kira berapa banyak fungsi yang kita tulis, kita boleh memanggil fungsi pemasaan ini untuk mengira masa pelaksanaan fungsi

Tetapi jika saya hanya mahu memanggil fungsi ini dengan cara asal f1(), f2(), fn (), Fungsi ini juga boleh menambah fungsi pengiraan masa manakala hasil keluaran pelaksanaan asal kekal tidak berubah. Daripada memanggil pemasa(f), pemasa(f2) boleh mengira masa.

Anda akan tahu cara menyelesaikan masalah ini selepas membaca fungsi penghias di bawah



1 Penghias - proses pembentukan

Berikut adalah penyelesaian A versi ringkas kod untuk soalan di atas:

import time

def f():
    print('hello')

def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

f = timer(f)
f()

Masih dengan ayat ini, saya hanya mahu memanggil fungsi ini dengan cara asal f1(), f2(), fn(), dan fungsi akan melaksanakan output dengan cara asal Fungsi mengira masa boleh ditambah sementara hasilnya kekal tidak berubah, tetapi saya masih perlu menulis f = pemasa(f) dalam rentetan kod ini sebelum fungsi f dilaksanakan menjengkelkan? Pembangun Python juga mendapati ia menjengkelkan, jadi pembangun Python menyediakan kami sintaks gula untuk menyelesaikan masalah ini!



2. Penghias - Pengenalan pertama kepada gula sintaksis

Gunakan @pemasa bukan f = pemasa(f), ini adalah ayat gula sintaksis.

import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> 写着这句话就相当于执行了f = timer(f)
def f():
    print('hello')


f()


3. Intipati - Intipati dan Fungsi

1 Intipati

Intipati penghias ialah Fungsi penutup <.> 2. Fungsi

Kembangkan fungsi asal tanpa mengubah fungsi asal dan kaedah panggilannya , Penghias - hiaskan penghias dengan parameter dan nilai pulangan

1. dengan parameter?

  • 2 Menghias berbilang fungsi dengan parameter berbeza tetapi tiada nilai pulangan

Sebenarnya, fungsi menghias dengan parameter bukanlah. sukar, tetapi bagaimana jika anda mempunyai dua fungsi dan parameter yang perlu dilalui adalah berbeza Contohnya, fungsi func1 mempunyai dua parameter func1(a,b), fungsi func2 hanya mempunyai satu parameter func2(a), dan semuanya mahu? untuk menggunakan hiasan Penghias ini untuk mengira masa pelaksanaan fungsi? Apa yang perlu dilakukan? Kemudian gunakan kod berikut.

import time
def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def f(a):
    print(a)

f('hello')
  • 3 Hiaskan berbilang fungsi dengan parameter berbeza dan nilai pulangan

Kini masalah parameter telah diselesaikan dengan sempurna Ya, tetapi bagaimana jika fungsi anda mempunyai nilai pulangan? Anda tidak boleh mendapatkan nilai pulangan dengan kod di atas Jadi bagaimana untuk menyelesaikan masalah ini? Kemudian lihat kod di bawah!

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func1(a,b):
    print('in func1')

@timer   #==> func2 = timer(func2)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'

func1('aaaaaa','bbbbbb')
print(func2('aaaaaa'))

输出结果:
in func1
0.0
in func2 and get a:aaaaaa
0.0
fun2 over
  • 4. Pelbagai penghias menghiasi fungsi yang sama

Kadangkala, kami juga menggunakan berbilang penghias untuk hiasan fungsi yang sama.

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func2 = timer(func2)
def func2(a):
    print('in func2 and get a:%s'%(a))
    return 'fun2 over'

func2('aaaaaa')
print(func2('aaaaaa'))

输出结果:
in func2 and get a:aaaaaa
0.0
in func2 and get a:aaaaaa
0.0
fun2 over
  • 5. Penghias - Kemajuan dan pengoptimuman penghias

1 🎜>Penghias di atas sudah sangat cantik, tetapi ada masalah lain Jika saya menambah gula sintaks @timer ke banyak fungsi dalam kod, bagaimana jika saya tidak mahu menggunakannya lagi dan bekerja siang dan malam selama tiga hari? Bukankah ia sangat menyusahkan? Untuk mengitar semula penghias dengan lebih baik apabila tidak digunakan dan bukannya menganotasi atau memadamnya satu persatu, kami memperkenalkan konsep penghias dengan parameter

'''
为了使装饰器不用时能够更好的回收而不是一个一个去注释或者删除
我们引入带参数的装饰器概念
'''

import time
'''FLAGE的目的是用它控制装饰器的开关,
那么当我们不用的时候就不要一个一个去注释只需将True改为False就行'''

FLAGE = True
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start = time.time()
                ret = func(*args,**kwargs)
                end = time.time()
                print(end - start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer
@timmer_out(FLAGE)

#timmer_out(FLAGE)
# 也相当于执行  timmer_out(FLAGE)--->>返回timmer———————>>@timmer(wahaha = timmer(wahaha))
def wahaha():
    time.sleep(0.1)         #不休息的话函数执行的太快难以计算时间
    print('wahahahahahaha')

wahaha()

@timmer_out(FLAGE)
def erguotou():
    time.sleep(0.1)         #不休息的话函数执行的太快难以计算时间
    print('erguotoutoutou')

erguotou()

输出结果:
wahahahahahaha
0.10152268409729004
erguotoutoutou
0.10795140266418457
  • 2、防止函数必要信息失效

'''
print(wahaha.__name__)      #查看字符串格式的函数名
print(wahaha.__doc__)       #查看一个函数的注释
'''
#下面用__name__查看holiday的函数名

from functools import wraps
def wrapper(func):
    @wraps(func)            #加在最内层函数正上方
    def inner(*args,**kwargs):
        print('在被装饰的函数执行之前做的事')
        ret = func(*args,**kwargs)
        print('在被装饰的函数执行之后做的事')
        return ret
    return inner

@wrapper        #holiday = wrapper(holiday)
def holiday(day):
    '''
    这是一个放假通知
    :param day:
    :return:
    '''
    print('全体放假%s天'%day)
    return '好开心'

print(holiday.__name__)
print(holiday.__doc__)
'''
结果是inner和None 但我们想要的是打印holiday的字符串格式的函数名和函数的注释这时该怎么办?
解决方法就是  from functools import wraps
使用语法是@wraps(被装饰的函数名)
'''

输出结果:
holiday

    这是一个放假通知
    :param day:
    :return:


六、装饰器 —— 装饰原则

  • 1、开放封闭原则

1.对原函数的功能扩展是开放的

        为什么要对功能扩展开放呢?

    对于任何一个程序来说,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许后来扩展、添加新功能。

2.对修改是封闭的

        为什么要对修改封闭呢?

                就像我们刚刚提到的,因为我们写的一个函数,很有可能在其他地方已经被导入使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经正在使用该函数的代码。

装饰器就完美遵循了这个开放封闭原则。这就是学装饰器的初衷



小结:

  • 1、装饰器的固定格式(模板)

#格式一

def timer(func):
    def inner(*args,**kwargs):
        '''执行函数之前要做的'''
        re = func(*args,**kwargs)
        '''执行函数之后要做的'''
        return re
    return inner

#格式二

from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

推荐学习:python

Atas ialah kandungan terperinci Melihat lebih dekat fungsi penghias Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:csdn.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam