python-day09

装饰器和匿名函数:

例一:实现计数功能:

def defunc(func):
    print('-------------------hello')
    count = 0
    def mapper(*args,**kwargs):
        nonlocal count
        print('欢迎调用{}函数第{}次'.format(func.__name__,count))
        func(*args,**kwargs)
        count+=1
    return mapper
@defunc
def show():
    print('这是显示函数show...')


for i in range(3):
    show()

'''
-------------------hello
欢迎调用show函数第0次
这是显示函数show...
欢迎调用show函数第1次
这是显示函数show...
欢迎调用show函数第2次
这是显示函数show...
'''

1、*args  **kwargs  在函数中的使用

如果想让装饰器函数达到通用性,则需要在内层函数中添加可变参数

这样无论装饰的函数是有参数还是没有参数,或者有关键字参数都可以装饰

2、要装饰的函数有返回值,装饰器的内层函数也要有返回值,从而保证装饰后的函数与原函数保持一致性。

  例:使用装饰器进行用户的登录验证:

islogin = False


def login_requierd(func):
    def wrapper(*args, **kwargs):
        global islogin
        if islogin:
            func(*args, **kwargs)
        else:
            print('-----------用户没有登录,请登录')
            f = login()
            if f:
                func(*args, **kwargs)
    return wrapper

def login():
    global islogin
    username = input('请输入用户名:')
    password = input('请输入密码:')
    if username == 'gang' and password == '123':
        islogin = True
        return islogin
    return islogin


@login_requierd
def buy_ticket():
    ticket = {'中关村店:': ('哪吒', ['11:35 一号厅', '12:15 二号厅', '13:45 三号厅'])}
    for key, value in ticket.items():
        print('影院', key)
        print('播放的电影是', value[0])
        print('播放的时间是:')
        for i in value[1]:
            print('--->', i)


# login()
buy_ticket()
'''
-----------用户没有登录,请登录
请输入用户名:gang
请输入密码:123
影院 中关村店:
播放的电影是 哪吒
播放的时间是:
---> 11:35 一号厅
---> 12:15 二号厅
---> 13:45 三号厅
'''
验证登录

3、装饰器参数:  三层函数实现的

def 装饰器名(参数):
    def  second(函数参数):
        def  third(*args,**kwargs):
                ....
                ....
            return third
    return second
def decorator(number):
    print('------>1')

    def decorator1(func):
        print('------->2')

        def wrapper(*args, **kwargs):
            print('-----start')
            func(*args, **kwargs)
            print('--------end')

        print('-------->3')
        return wrapper

    print('------->4')
    return decorator1

@decorator(10)
def show():
    print('------->调用show函数')

show()
'''
------>1
------->4
------->2
-------->3
-----start
------->调用show函数
--------end
'''

 4、多层装饰器:

谁离原函数最近先执行哪个装饰器,将第一层装饰器的返回结果传给第二层装饰器

最后:原函数得到的地址是第二层函数的返回值wrapper

def decorator1(func):
    def wrapper(*args,**kwargs):
        func(*args,**kwargs)
        print('刷地板')
        print('刷漆')
    return wrapper

def decorator2(func):
    def wrapper(*args,**kwargs):
        func(*args,**kwargs)
        print('买家具')
        print('买沙发')
        print('买装饰品')
    return wrapper

@decorator2
@decorator1
def house():
    print('----------未装修房子')

print(house)
house()

'''
<function decorator2.<locals>.wrapper at 0x000001A795094510>
----------未装修房子
刷地板
刷漆
买家具
买沙发
买装饰品
'''

 5、匿名函数:

定义格式:  lambda  参数:返回值

使用:1、函数体非常简单  2、使用次数较少

f = lambda n:n+1
print(f)
r = f(5)
print(r)

f1 = lambda x,y:x+y
r = f1(1,2)
print(r)

例子:

list1 = [('tom',12),('lucy',20),('lily',16),('luze',19),('jerry',34)]
list2 = sorted(list1,key=lambda x:x[1],reverse=True)
print(list2)
#[('jerry', 34), ('lucy', 20), ('luze', 19), ('lily', 16), ('tom', 12)]

6、高阶函数:把函数当成参数进行传递的函数

  1》sorted(iterable,key,reverse)  其中key就是一个函数参数

dict1 = {'tom':12,'lucy':20,'lily':16,'luze':19,'jerry':34}
result = sorted(dict1.items(),key=lambda x:x[1])
dict1 = dict(result)
print(dict1)
#{'tom': 12, 'lily': 16, 'luze': 19, 'lucy': 20, 'jerry': 34}

  2》map映射  map(function,iterable)

    给一个可以迭代的对象,通过function的作用,将其转成一个新的对象

map1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(map1)
print(list(map1))
# <map object at 0x0000023D21830C18>
# [1, 4, 9, 16, 25]

names = ['tom', 'java', 'c#', 'python']
map2 = map(lambda x: x.capitalize(), names)
print(list(map2))  # ['Tom', 'Java', 'C#', 'Python']

map0 = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(map0))  # [5, 7, 9]

   3》filter(function,iterable):返回值是一个filter

    需要对返回值进行转换:list(filter_object)

    function函数的返回值必须是bool类型

num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 13, 24]
filter1 = filter(lambda x: x % 2 == 0, num)
print(list(filter1))  # [2, 4, 6, 8, 0, 10, 24]
list1 = ['hello', 67, 'nihao', '99', '25', 'gang']
filter1 = filter(lambda x: str(x).isdigit(), list1)
print(list(filter1))  # [67, '99', '25']

filter2 = filter(lambda x: isinstance(x, int) or x.isdigit(), list1)
print(list(filter2))  # [67, '99', '25']

   4》reduce(function,iterable)

    参数function是函数,此函数的参数必须两个  lambda  x,y:x*y

    参数iterable是一个可迭代对象

from functools import reduce

list1 = [1, 2, 3, 5]
result = reduce(lambda x, y: x + y, list1, 2)
print(result)  # 13

result = reduce(lambda x, y: x + y, range(1, 7))
print(result)  # 21

7、functools模块

  partial()    偏函数  是通过将一个函数的部分参数预先绑定为某些值,从而得到一个新的具有较少可变参数的函数。

from functools import partial,wraps
int1 = partial(int,base=8)
print(int1('123'))  # 83

  wraps()    消除装饰器带来的一些副作用

    获取对象名:    house.__name__     获取函数名     house.__doc__    获取文档注释

python装饰器:在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)为了不影响,python的functools包中提供了一个叫wraps的decorator来消除这样的副作用。

from functools import partial, wraps


def decorator1(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        func(*args,**kwargs)
        print('铺地板')
        print('刷漆')
    return wrapper
def house():
    print('----------未装修房子')

print(house.__name__)
print(house.__doc__)

house()
# house
# None
# ----------未装修房子

8、列表推导式:

 格式:[表达式 for i in list|set|tuple|dict  [if 条件]]

 格式:[表达式1 if 条件 else 表达式2 for i in list|set|tuple|dict  [if 条件]]

 格式:[表达式 for i in list|set|tuple|dict  for i in list|set|tuple|dict ]

list1 = [1,3,5,2,5,7]
list2 = [x for x in list1 if x%2==0]
print(list2)  #[2]
list3 = [x+1 if x%2==0 else x+2 for x in list1]
print(list3)  # [3, 5, 7, 3, 7, 9]

list0 = [1,2,3]
list4 = [2,4,6]
list5 = [(x,y) for x in list0 for y in list4]
print(list5)
# [(1, 2), (1, 4), (1, 6), (2, 2), (2, 4), (2, 6), (3, 2), (3, 4), (3, 6)]

猜你喜欢

转载自www.cnblogs.com/rungang/p/11288456.html