Python装饰器概述与字符串补充

冷暖自知 提交于 2019-12-10 23:51:27

一.字符串的补充

如何快速生成验证码等无序、限定个数的码

import random
import string
print(string.ascii_letters)
print(string.ascii_lowercase)
print(string.ascii_uppercase)
print(string.digits)

# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
# abcdefghijklmnopqrstuvwxyz
# ABCDEFGHIJKLMNOPQRSTUVWXYZ
# 0123456789

print(string.ascii_letters+string.digits)

# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
lie=string.ascii_letters+string.digits

print(random.sample(lie,5))

# ['2', 'r', 'D', 'j', 'T']
def random_code(len=4):
    #写法1
    # code=''
    # for i in range(len):
    #     newcode=random.choice(lie)
    #     code += newcode
    # return code
    #写法2
    return ''.join(random.sample(lie,len))

print(random_code())

#Zi26   #写法1结果
#fkwm   #写法2结果
print(random_code(6))

#uuhXyX #写法1结果
#dxaLtZ #写法2结果

二.装饰器

把一个函数当作参数传递给另一个函数,返回一个替代版的函数,装饰器本质上就是一个返回函数的函数,如下面的outer

在不改变原函数的基础上,给函数增加新的功能(不止是可以装饰)

1、

def outer(f):
    def inner():
        print('***********')
        f()
        print('***********')
    return inner
def A():
    print('yeah')
A=outer(A)            #由于outer返回的是一个函数,不能直接打印函数,所以将新函数赋值给一个变量
A()                   #再调用这个新的函数

# ***********
# yeah
# ***********

@outer    #语法糖
def B():
    print('is B')
B()

# ***********
# is B
# ***********

2、用装饰器实现一些功能

def age(x):		
    print("%d岁了" %x)	

# age(-10)
# -10岁了
def outer(f):
    def inter(x):
        if x <=0:
            x = 0
        f(x)
    return inter

@outer
def age(x):
    print("%d岁了" %x)

age(-10)

#0岁了

3、用装饰器实现一个函数计时器的功能

import functools
import random
import string
import time
lie=[random.choice(string.ascii_letters+string.digits) for i in range(1000)]

def TimE(f):
    @functools.wraps(f)
    def inner(*args,**kwargs):            #接收可变参数和关键字参数
        """this is TimE"""
        starttime=time.time()
        res=f(*args,**kwargs)
        stoptime=time.time()
        print("用时:%.6f" %(stoptime-starttime))
        return res
    return inner
# @TimE
# def A():
#     s=''
#     for i in lie:
#         s += i
#     print(s)
# @TimE
# def B():
#     print(''.join(lie))
# A()
# B()

#用时:0.000139
#用时:0.000018
@TimE
def test1(n):
    return [2*i for i in range(n)]
@TimE
def test2(n):
    return list(map(lambda x:x*2,range(n)))

test1(100000)
test2(100000)

# 用时:0.009022
# 用时:0.017944
def test3(n):
    """this is test3"""
    return list(map(lambda x:x*2,range(n)))

print(test3.__name__)     #显示函数名称
print(test3.__doc__)      #显示函数中注释的内容
# test3
# this is test3

@TimE
def test3(n):
    """this is test3"""
    return list(map(lambda x:x*2,range(n)))

print(test3.__name__)
print(test3.__doc__)

# inner             #会显示为装饰器内的信息
# this is TimE

# 可在装饰器中加入@functools.wraps(f)解决

# test3
# this is test3     #在装饰器中加入后显示的信息

4、多个装饰器的使用

import functools


def zhuangA(f):
    @functools.wraps(f)
    def inter(*args,**kwargs):
        print("this is A")
        res=f(*args,**kwargs)
        return res
    return inter

def zhuangB(f):
    @functools.wraps(f)
    def inter(*args, **kwargs):
        print("this is B")
        res = f(*args, **kwargs)
        return res
    return inter

@zhuangA
@zhuangB
def new():
    print("this is new")
new()
#该实验的意义在于,表现出多个装饰器同时调用时,自上至下运行
# this is A       #首先调用了装饰器A
# this is B       #其次调用了装饰器B
# this is new     #最后再输出函数值

三.综合练习题

综合练习题1:

创建add_log装饰器,被装饰的函数打印日志信息,日至格式为:[字符串时间] 函数名:xxx,运行时间:xxx,运行返回值结果:xxx

import time
import functools

def add_log(f):
    @functools.wraps(f)
    def inter(*args,**kwargs):
        starttime=time.time()
        res=f(*args,**kwargs)
        stoptime=time.time()
        time1=stoptime-starttime
        print(time.ctime()+"," +f.__name__+"," +str(time1)+","+str(res))
        return res
    return inter
@add_log
def test3(n):
    return list(map(lambda x:x*2,range(n)))

test3(10)
综合练习题2:

编写required_ints函数,使输入的数据必须全为整形

import functools
def required_ints(f):
    functools.wraps(f)
    def inter(*args,**kwargs):
        for i in args:
            if not isinstance(i,int):
                print("error:参数必须全为整形")
        else:
            res=f(*args,**kwargs)
            return res
    return inter

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

print(add(2,1.3))
#error:参数必须全为整形

print(add(1,2))

#3
综合练习题3:

升级版装饰器(可选择参数类型的)
编写装饰器required_types,条件如下:
1.当装饰器为required_types(int,float)时,确保函数接收到的每一个参数都是int型或float型
2.当装饰器为required_types(list)时,确保函数接收到的每一个参数都是list型
3.当装饰器为required_types(str,int)时,确保函数接收到的每一个参数都是str型或int型
4.当参数不满足条件时,打印error,提示参数必须为xxx类型

import functools
def required_types(*kind):
    def required_ints(f):
        functools.wraps(f)
        def inter(*args,**kwargs):
            for i in args:
                if not isinstance(i,kind):
                    print("error:参数需是%s型" %kind)
                    break
            else:
                res=f(*args,**kwargs)
                return res
        return inter
    return required_ints

# @required_types(int)
# def add(a,b):
#     return a+b
# print(add(1,1.2))

#error:参数需是<class 'int'>型
#None

@required_types(int,float)
def add(a,b):
    return a+b
print(add(1,1.2))

#2.2

@required_types(float)
def add(a,b):
    return a+b
print(add(1,1.2))

#error:参数需是<class 'float'>型
#None

@required_types(list)
def add(a,b):
    return a+b
print(add([1,2,3],[4,5,6]))

#[1, 2, 3, 4, 5, 6]

@required_types(str)
def add(a,b):
    return a+b
print(add('123','abc'))

#123abc
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!