zoukankan      html  css  js  c++  java
  • day13 多个装饰器叠加 生成式

    1.装饰器剩余

    from functions import wraps

    @wrap(func) 会把func内的自带方法赋给wrapper,这样wrapper装饰函数就和原函数一模一样

    多个装饰器叠加

    def outter1(func):

      def wrapper1(*args,**kwargs):

        res = func(*args,**kwargs)

        return res

      return wrapper1

    def outter2(func):

      def wrapper2(*args,**kwargs):

        res = func(*args,**kwargs)

        return res

      return wrapper2

    def outter3(func):

      def wrapper3(*args,**kwargs):

        res = func(*args,**kwargs)

        return res

      return wrapper3

    @outer1

    @outer2

    @outer3

    def f1(name):

      print('welcome home %s' % name)

    f1('egon')

    加载顺序

    自下而上,因为装饰器的语法糖,相当于f1 = outer1(outer2(outer3(f1)))

    检测语法后,先加载outer3,此时的原函数f1的内存地址还没有变包在闭包函数wrapper3中传给outer2,outer2将打包的闭包函数wrapper2地址传给outer1,outer1将打包的闭包函数打包给f1

    outer1(outer2(outer3(f1))) 从右往左一步一步闭包并且加载函数

    执行顺序 从上往下,因为用到的闭包函数都被包给了outer1中,先去outer1中开始运行,运行到其中要运行wrapper2的地方了,这时wrapper1还没运行完,就跳到wrapper2中去执行,wrapper2还没执行完,遇到wrapper3了,就跳到wrapper3中运行,运行完已经是最内层了,开始把wrapper3的返回值返回值给wrapper2,wrapper2运行完返回值返回给wrapper1,wrapper1运行完之后,返回值返回给最初始的函数,继续运行全局代码,整个装饰器函数的调用结束。

    2.有参装饰器

    以上装饰器模版如下

    from functools import wraps

    def outter(func):

      @wraps(func)

      def wrapper(*args,**kwargs):

        res = func(*args,**kwargs)

        return res

      return wrapper

    这样会遇到一个问题,这个函数确实可以完全模仿了旧函数的同时加了新功能,但是如果假如想给内部闭包函数传进其他参数方便使用,在当前模版上就没法做到

    outter(func)的参数必须是原函数,不能增加,也不能减少,否则使用语法糖@outter func=outter(func)会报错

    另外,wrapper(*args,**kwargs)内传的参数也不能改变,这是为了把原函数的参数原封不动还给原函数去调用

    这个时候,就可以再多包一层函数,在最外层函数传参数,而且参数可以任意指定,把最外层函数名返回,这样包含着最外层名称空间的闭包函数就赋给了原函数

    既包含旧功能,又添加了新功能,还传了新参数,可供程序扩展使用

     根据传进的文件类型不同,在内部增加判断选择写入文件的方式

    3.三元表达式

    三元表达式用来在保证代码可读性的前提下,精简一些语句的写法

    如下需要函数判断两个数的大小语句

    def max(x,y)

      if x>y:

        return x

      else:

        return y

    可以用如下表达式代替

    x=10

    y=20

    res = x if x >y else y #b表达式1 if条件表达式 else 表达式2,当if判断返回True时,返回结果表达式1,否则返回结果表达式2

    print(res)

    res = ’ok‘ if False else 'No'

    print(res) 

    4.生成式:用来生成数据的表达式

    先来生成一个列表

    l = []

    for i in range(10):

      if i >4:

        l.append(i**2)

    列表生成式

    l = [i**2 for i in range(10) if i >4] 不能加else,因为不知道是加给for的还是if的

    print(l)

    name = ['egon','alex_sb','kevin_sb','hxx_sb','cxx_sb'] 匹配找出结尾是sb的元素

    sbs=[]

    for name in names:

      if name.endswith('sb')

        sbs.append(name)

    用生成式代替

    sbs = [name for name in names if name.endswith('sb')]

    print([name.upper() for name in names])

    字典生成式

    res = {i:i**2 for i in range(10) if i > 3}

    print(res)

    print({i for i in 'hello'}) 生成集合,去重

    5.匿名函数

    先看有名函数

    def func():

      print(‘from func’)

    func()

    func()

    func()

    有名称的函数定义后,可以在之后多次以名字调用

    匿名函数就是只定义一个函数的内存地址,主要用于临时使用一次的场景

    func = lambda x,y:(return)x+y 匿名函数自动返回值,不用添加return

    print(func)

    print(func(1,2))

    res = (lambda x,y:x+y)(1,2) 匿名函数后面加扣号调用,并传参数

    print(max([10,11,-3,23]))

    salaries = {

    'egon':3000

    'alex':100000000

    'wupeiqi':10000

    'yuanhao':2000

    }

    def func(k):

      return salaries[k]

    print(max(salaries,key = lambda  k:salaries[k]))

  • 相关阅读:
    CBUUID UUIDString unrecognized selector sent to instance 错误
    利用php的序列化和反序列化来做简单的数据本地存储
    php 执行外部命令exec() system() passthru()
    php 使用 restler 框架构建 restfull api
    使用ar命令删除iOS静态库重复编译的.o文件
    c++ string 与 char 互转 以及base64
    CLGeocoder Error Domain=kCLErrorDomain Code=2
    mac air/pro 启用三指拖动手势
    osx 10.11.5 El Capitan U盘制作安装
    php cli模式下获取参数的方法
  • 原文地址:https://www.cnblogs.com/shanau2/p/10044890.html
Copyright © 2011-2022 走看看