资讯专栏INFORMATION COLUMN

python_bomb----小白学装饰器

mikasa / 3114人阅读

什么是装饰器?

装饰器就是用来装饰函数。

想要增强原有函数的功能

但不希望修改原有函数的定义

在代码运行期间动态增加功能的方式

函数嵌套函数

调用方式:
原函数 = 外层函数(原函数名)
原函数

def desc(fun):
    def add_info():
        print("happy today")
        fun()
        print("westos_linux")
    return add_info
def login():
    print("login..")

login = desc(login)
login()

def add_info(fun):
    print("happy today")
    fun()
    print("westos_linux")
def login():
    print("login..")
def logout():
    print("logout..")
def save():
    print("save..")
def trans():
    print("trans")

add_info(login)
add_info(logout)
login = add_info(login)

装饰器使用

定义的装饰器实质是返回函数的高阶函数
@timeIt(装饰器名) 这里是 python 提供的一个语法糖
1.解决问题:函数执行前后添加功能-->会改变函数调用命令
2.不改变原有函数的调用方式-->函数里面嵌套函数,并且不改变返回嵌套函数的调用方式-->login = desc(login)

计时装饰器
需求:获取每个函数的执行时间
#1.函数执行之前计算时间
#2.函数执行之后计算时间

import random
import string
import time
from functools import reduce

li = [random.choice(string.ascii_letters +string.digits) for i in range(10) ]

def timeit(fun):
    def wrapper(*args,**kwargs):
        t1=time.time()
        res = fun(*args,**kwargs)
        t2 = time.time()
        grot = t2-t1
        print("所需时间:%.6f" %grot)

        return res
    return wrapper

@timeit
def myjoin(*args,**kwargs):
    s = ",".join(*args,**kwargs)
    print(s)

myjoin(li)

日志装饰器
#创建装饰器
#1.创建add_log装饰器,被装饰函数打印日志信息
#2.日志格式为:[字符串时间] 函数名:XXX 运行时间:XXXX 运行返回值结果:XXXX
import time
import functools
import math
def add_log(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        run_time =time.ctime()
        start_time  = time.time()
        res = fun(*args,**kwargs)
        end_time = time.time()
        na = fun.__name__
        print("[字符串时间:%s] 函数名:%s 运行时间:%.6f 运行返回值结果:%s" %(run_time,na,end_time-start_time,res))
        return res
    return wrapper

@add_log
def mymult(x,y):
    """这是一个求x的y次方的函数"""
    return math.pow(x,y)
mymult(2,3)

登陆验证
#用户登录验证的装饰器is_login
#   如果用户登陆成功,则执行被装饰的函数
#   如果用户登陆不成功,则执行登陆函数


users =["root","sheen"]
def is_login(fun):
    def wrapper(*args,**kwargs):
        if kwargs.get("name") in users:
            res  = fun(*args,**kwargs)
        else:
            res = login()
        return res
    return wrapper

@is_login
def writeblog(name):
    return "wirte,now.."

def login():
    return "please login.."

print(writeblog(name="star"))

类型判断(无参)
#1.基础版(无参数)
#编写装饰器required_ints
#   确保函数收到的每一个参数都是整数
#   如果参数不是整形数,打印TypeError
import functools

def required_ints(fun):
    @functools.wraps(fun)
    def wrapper(*args,**kwargs):
        for i in args:
            if not isinstance(i,int):
                print("TypeError")
                break
        else:
            res = fun(*args,**kwargs)
            return res

    return wrapper

@required_ints
def myadd(a,b):
    return a+b

print(myadd(1,2.0))

含参类型判断
# #带参数的装饰器
# """
# 装饰器为required_types
#     当装饰器为@required_types(int,float),确保函数接收到的每一个参数都是int/float类型
#     当装饰器为@required_types(list),确保函数接收到的每一个参数都是list类型
#     当装饰器为@required_types(str,int),确保函数接收到的每一个参数都是str/int类型
#     如果参数不满足条件,打印TypeError,参数必须是XXXXX类型
import functools
def required_types(*kinds): #kinds元组
    def required_ints(fun):
        @functools.wraps(fun)
        def wrapper(*args,**kwargs):
            for i in args:
                if  not isinstance(i,kinds):
                    print("TypeError,参数类型为",kinds)
                    break
            else:
                res = fun(*args,**kwargs)
                return res

        return wrapper
    return required_ints

@required_types(int,str)
def my(a,b):
    return a,b
print(my(1,"sdhs"))

带有多个装饰器
def makebold(fun):
    print("makebold")
    def wrapper1(*args,**kwargs):
        print("bold")
        return fun(*args,**kwargs)
    return wrapper1

def makei(fun):
    print("makei")
    def wrapper(*args,**kwargs):
        print("i")

        return fun(*args, **kwargs)
    return wrapper  #wrapper=login

#当有多个装饰器时,从下到上调用装饰器
#真实wrapper内容是从上到下执行的
@makebold   #login = makebold(login)    #login为wrapper1
@makei      #login = makei(login)       #login为wrapper
def login():
    return "登陆"

print(login())

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42276.html

相关文章

  • python_bomb----有趣的微信聊天机

    摘要:模块是一个文件,以结尾,包含了对象定义和语句模块让你能够有逻辑地组织你的代码段。把相关的代码分配到一个模块里能让你的代码更好用,更易懂。命令执行成功,执行结果命令执行失败一秒后执行关机命令 Python 模块(Module) 是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句 模块让你能够有逻辑地组织你的 Python 代码段。 把相关的代...

    bawn 评论0 收藏0
  • python_bomb----包

    摘要:什么是包为了组织好模块,会将多个模块分为包。处理包也是相当方便的。简单来说,包就是文件夹,但该文件夹下必须存在文件。最简单的情况下,只需要一个空的文件即可。当然它也可以执行包的初始化代码包底下也能包含包,这和文件夹一样,还是比较好理解的。 什么是包? 为了组织好模块,会将多个模块分为包。Python 处理包也是相当方便的。简单来说,包就是文件夹,但该文件夹下必须存在 __init__....

    LeanCloud 评论0 收藏0
  • 前端也要系列:设计模式之装饰者模式

    摘要:什么是装饰者模式今天我们来讲另外一个非常实用的设计模式装饰者模式。就增加功能来说,装饰者模式相比生成子类更为灵活。下面,装饰者模式就要正式登场了。下一步,我们可以愉快的去使用装饰者模式啦 什么是装饰者模式 今天我们来讲另外一个非常实用的设计模式:装饰者模式。这个名字听上去有些莫名其妙,不着急,我们先来记住它的一个别名:包装器模式。 我们记着这两个名字来开始今天的文章。 首先还是上《设计...

    高胜山 评论0 收藏0
  • Python知识点:理解和使用装饰 @decorator

    摘要:使用类装饰器,优点是灵活性大,高内聚,封装性。不过不用担心,有,本身也是一个装饰器,它的作用就是把原函数的元信息拷贝到装饰器函数中,使得装饰器函数也有和原函数一样的元信息。 showImg(https://segmentfault.com/img/bVbrFWb?w=742&h=484);Python的装饰器(decorator)是一个很棒的机制,也是熟练运用Python的必杀技之一。...

    cyqian 评论0 收藏0
  • [python] 初探'函数式编程'

    摘要:前言继续向下看廖大教程,看到了函数式编程这一节,当时是觉得没啥用直接跳过了,这次准备要仔细看一遍了,并记录下一些心得。 前言 继续向下看廖大教程,看到了函数式编程这一节,当时是觉得没啥用直接跳过了,这次准备要仔细看一遍了,并记录下一些心得。 函数式编程 上学期有上一门叫 人工智能 的课,老师强行要我们学了一个叫做 prolog 的语言,哇那感觉确实难受,思维方式完全和之前学过的不一样,...

    xcc3641 评论0 收藏0

发表评论

0条评论

mikasa

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<