【Python中的】装饰器和第三方模快的简单实例

本文深入讲解了Python装饰器的基本概念及应用,通过多个实例演示了装饰器如何在不修改原始函数的情况下为其添加新功能,包括日志记录、性能测试、参数验证等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

         装饰器本质是一个Python函数,它可以让其他函数在不需要作任何

代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象,

它经常用于有切面需求的场景,比如插入日志、性能测试、事物处理、缓

存、权限校验等场景,装饰器是解决这类问题的绝佳设计,有了装饰器,

我们就可以抽离出大量于函数的功能本身无关的雷同代码并继续使用。

 

正文:

一、装饰器的基础练习

装饰器:

把一个函数当作参数,返回一个替代版的函数,本质就是一个返回函数的

函数,在不改变元函数的基础上增加函数的功能,

1、示例1:

def des(fun):
    def add_info():
         print('清明节快乐')
         fun()
    return add_info

@des
def login():
    print('hello world')

@des
def logout():
    print('hello westos')

login()
logout()

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/装饰器.py
清明节快乐
hello world
清明节快乐
hello westos

Process finished with exit code 0

 

示例2:函数对修改是封闭的,对扩展是开放的

import time
def sec(fun):
    def add_info():
        a = time.time()
        fun()
        b=time.time()
        c = b - a
        print('时间差为:%.10f' %(c))
    return add_info


@sec
def f1():
    print(time.time())
    print('This is a function')


@sec
def f2():
    print(time.time())
    print('This is a function2')

f1()
f2()

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/装饰器练习2.py
1554631396.7552593
This is a function
时间差为:0.0000474453
1554631396.7553174
This is a function2
时间差为:0.0000092983

Process finished with exit code 0

 

示例3、含参数的装饰器

import time
def decoator(fun):
    def  wropper(*args):
        print(time.time())
        fun(*args)
    return wropper

@decoator
def f1(fun_name):
    print('This is a function' + ' ' + fun_name)

@decoator
def f2(fun_name):
    print('This is a function' + ' ' + fun_name)


f1('1,2,3,4')
f2('4,5,6,7')

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/含参数的装饰器.py
1554632121.0207565
This is a function 1,2,3,4
1554632121.0207922
This is a function 4,5,6,7

Process finished with exit code 0

 

示例4、包含多个参数和关键数参数的装饰器

import time
def  decortor(fun):
     def warrper(*args,**kwargs):
         print(time.time())
         fun(*args,**kwargs)
     return warrper

@decortor
def f1(function_name1,function_name2,**kwargs):
    print('This is a function' + '' + function_name1)
    print('This a function' + '' + function_name2)
    print(kwargs)

f1('test','test2',a=2,b=3,c=5)

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/含关键字的装饰器.py
1554633214.0698268
This is a functiontest
This a functiontest2
{'a': 2, 'b': 3, 'c': 5}

Process finished with exit code 0

 

示例5、

import time
def add_log (fun):
    def wropperr(*args,**kwargs):
        start= time.time()
        res = fun(*args,**kwargs)
        endtime = time.time()
        print('运行时间为:%.6f,函数返回值为:%d' %((endtime-start),res))
    return wropperr

@add_log
def add(x,y):
    return x + y
add(2,2)

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/装饰器5.py
运行时间为:0.000008,函数返回值为:4

Process finished with exit code 0

 

示例6、进行多个装饰器的练习

注意的是:当函数遇到多个装饰器时,执行顺序为,要添加函数外面的

代码执行顺序为从下到上,添加函数内部执行顺序为从下到上

def dectors_a(fun):
    print('Get in decotor_a')

    def inner_a(*args,**kwargs):
        print('Ger in inner_a')
        res = fun(*args,**kwargs)
        return res

    return inner_a

def dector_b(fun):
    print('Get in dector_b')

    def inner_b(*args,**kwargs):
        print('Get in inner_b')
        res = fun(*args,**kwargs)
        return res
    return inner_b

@dector_b
@dectors_a
def add(x,y):
     return x + y

add(1,3)

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/多个装饰器的练习.py
Get in decotor_a
Get in dector_b
Get in inner_b
Ger in inner_a

Process finished with exit code 0

 

二、进行装饰器的练习:

1、需求:

:问题1:被装饰的函数有返回值
:问题2:如何保留被装饰函数的函数名和帮助信息文档

import time
import random
import string
import functools
li = [random.choice(string.ascii_letters) for i in range(100)]
print(li)

def Tinner(fun):
    def wropper(*args,**kwargs):
        start = time.time()
        res = fun(*args,**kwargs)
        endtime = time.time()
        print('运行时间为:.%.6f' %(endtime-start))
        return res

    return wropper
@Tinner
def com_add():
    s= ''
    for i in li:
        s += (i + ',')
    print(s)

@Tinner
def join_add():
    print(''.join(li))

@Tinner
def fun_list(n):
    return [i * 2 for i in range(n)]




print(fun_list(10))
join_add()
print(fun_list.__doc__)
print(fun_list.__name__)   ###装饰器中添加函数的名称
print(time.ctime())        ###装饰器中调用的时间

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/装饰器的练习1.py
['p', 'z', 'l', 'o', 'H', 'T', 'V', 'X', 'u', 'F', 'x', 'j', 'X', 'g', 't', 'U', 'S', 'i', 'j', 'a', 'I', 'k', 'i', 'v', 'f', 'v', 'Z', 'R', 'B', 'E', 'v', 'M', 'L', 'E', 'B', 'r', 'L', 'g', 'B', 'B', 'K', 'O', 'O', 'u', 'E', 'b', 'j', 'g', 'r', 'b', 'x', 'R', 'x', 'n', 'n', 'k', 'I', 'K', 'y', 'I', 'B', 'D', 'Q', 'C', 'K', 'x', 'x', 'L', 'X', 'Q', 'G', 'L', 'O', 'd', 'g', 'y', 'C', 'x', 'A', 'M', 'A', 'b', 'P', 'a', 'X', 'B', 'i', 's', 'F', 'u', 'g', 'h', 'M', 'w', 'l', 'C', 'L', 'c', 'Q', 'k']
运行时间为:.0.000003
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
pzloHTVXuFxjXgtUSijaIkivfvZRBEvMLEBrLgBBKOOuEbjgrbxRxnnkIKyIBDQCKxxLXQGLOdgyCxAMAbPaXBisFughMwlCLcQk
运行时间为:.0.000005
None
wropper
Mon Apr  8 00:12:46 2019

Process finished with exit code 0

 

练习2、

import functools
import inspect
def is_admin(fun):
    @functools.wraps(fun)
    def weapper(*args,**kwargs):
        #inspect.gercallargs返回是一个字典,key值是形参,value值是对应的实参
        inspect_res = inspect.getcallargs(fun,*args,**kwargs)
        print('insepect的返回值为:%s'%(inspect_res))
        if inspect_res.get('name') == 'root':
            res = fun(*args,**kwargs)
            return res
        else:
            print('not root user!')
    return weapper
@is_admin
def add_user(name):
    print('添加用户信息')

@is_admin
def del_user(name):
    print('删除用户信息')

add_user('root')
del_user('root')

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/imspect中的装饰器.py
insepect的返回值为:{'name': 'root'}
添加用户信息
insepect的返回值为:{'name': 'root'}
删除用户信息

Process finished with exit code 0

 

练习3、

"""
编写装饰器required_types, 条件如下:
1). 当装饰器为@required_types(int,float)确保函数接收到的
每一个参数都是int或者float类型;
2). 当装饰器为@required_types(list)确保函数接收到的每一个参数都是list类型;
3). 当装饰器为@required_types(str,int)确保函数接收到的每
一个参数都是str或者int类型;
4). 如果参数不满足条件, 打印 TypeError:参数必须为xxxx类
型
"""
"""
编写装饰器required_types, 条件如下:
1). 当装饰器为@required_types(int,float)确保函数接收到的
每一个参数都是int或者float类型;
2). 当装饰器为@required_types(list)确保函数接收到的每一个参数都是list类型;
3). 当装饰器为@required_types(str,int)确保函数接收到的每
一个参数都是str或者int类型;
4). 如果参数不满足条件, 打印 TypeError:参数必须为xxxx类
型
"""

import functools
def required_type(*kinds):
    def required_int(fun):
        @functools.wraps(fun)
        def wropper(*args,**kwargs):
            for i in args:
                if not isinstance(i,kinds):
                    raise TypeError('参数必须为%s,%a'% kinds)
                else:
                    res = fun(*args,**kwargs)
                    return res
        return wropper
    return required_int

def add(a,b):
    return a + b
print(add('s','s'))

执行结果:
/home/kiosk/PycharmProjects/westos6/venv/bin/python /home/kiosk/PycharmProjects/westos6/装饰器的练习3.py
ss

Process finished with exit code 0

 

三、Python 中的第三方模块

示例1:第三方模块指的是别人写好的一些模块,可以实现一定的功能

实现给微信发送指定的内容

import random
import time

import itchat

itchat.auto_login()

while True:
 itchat.send('welcome use weixin',toUserName='filehelper')
 itchat.send_file('/etc/passwd',toUserName='filehelper')
 time.sleep(random.randint(1,3))

执行结果:
/home/kiosk/PycharmProjects/westos7/venv/bin/python /home/kiosk/PycharmProjects/westos7/第三方模快.py
Getting uuid of QR code.
Downloading QR code.
Please scan the QR code to log in.
Please press confirm on your phone.
Loading the contact, this may take a little while.
Login successfully as 左手边

 

2、使用第三方模块实现统计微信中的好友

import random
import time

import itchat

itchat.auto_login()

friends = itchat.get_friends()
info = {}

for friend in friends[1:]:
    if friend['Sex'] == 1:
        info['male'] = info.get('male',0) + 1
    elif friend['Sex'] == 2:
        info['female'] = info.get('female',0) + 1
    else:
        info['other'] = info.get('other',0) + 1

print(info)

执行结果:
/home/kiosk/PycharmProjects/westos7/venv/bin/python /home/kiosk/PycharmProjects/westos7/第三方模快.py
Getting uuid of QR code.
Downloading QR code.
Please scan the QR code to log in.
Please press confirm on your phone.
Loading the contact, this may take a little while.
Login successfully as 左手边
{'male': 57, 'other': 11, 'female': 39}

Process finished with exit code 0

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值