第四课 函数补充--装饰器、迭代器、生成器、匿名函数、递归函数

1、装饰器(补充) (在原有的函数前后增加功能,且不改变原函数的调用方式)

  1.1、简单的装饰器构成:

  def timer(func):
      def inner(*args,**kwargs):
          ‘‘‘执行函数之前要做的‘‘‘
          re = func(*args,**kwargs)
          ‘‘‘执行函数之后要做的‘‘‘
          return re
      return inner
def outer(flag):
    def timer(func):
        def inner(*args,**kwargs):
            if flag:
                print(‘‘‘执行函数之前要做的‘‘‘)
            re = func(*args,**kwargs)
            if flag:
                print(‘‘‘执行函数之后要做的‘‘‘)
            return re
        return inner
    return timer

@outer(False)
def func():
    print(111)

func()
  1.2、设计是否生效的装饰器(加判断),在装饰器的最外层再加一层函数做判断
# 进阶的需求
# 第一种情况
#     500个函数
#     你可以设计你的装饰器 来确认是否生效

import time
FLAG = True #设置的变量来判断
def outer(flag):
    def timmer(f):
        def inner(*args,**kwargs):
            if flag == True:
                start_time = time.time()
                ret = f(*args,**kwargs)
                end_time = time.time()
                print(end_time - start_time)
            else:
                ret = f(*args, **kwargs)
            return ret
        return inner
    return timmer
#
@outer(FLAG)   # func = timmer(func) # 外层函数来判断变量
def func(a,b):
    print(‘begin func‘,a)
    time.sleep(0.1)
    print(‘end func‘,b)
    return True
func(1,2)

  1.3、多个装饰器的执行执行顺序:


当存在多个装饰器时,从下往上执行装饰器:
def wrapper1(func):                   #3  func = f
    def inner1():            #14           
        print(‘wrapper1 ,before func‘)#15
        func()                         #16
        print(‘wrapper1 ,after func‘) #17
    return inner1                     #4 f = inner1

def wrapper2(func):           #7 func = f
    def inner2():            #11
        print(‘wrapper2 ,before func‘) #12
        func()               #13   func() = f() = inner1()
        print(‘wrapper2 ,after func‘)  #18
    return inner2            #8 f = inner2

@wrapper2  #f = wrapper2           #6    #9   f = inner2
@wrapper1  #f = wrapper1          #2    #5   f = inner1
def f():                              #1
    print(‘in f‘)             #16
f() #走到这步时才真正的开始执行函数        #10 真正开始执行,按顺序往回找:这时 f() = inner2()

在执行函数之前,先进行装饰器的加载。

执行结果:

wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func

总结:后执行的放在上面,先执行的放在下面
# # 装饰器 登录 记录日志
# import time
# login_info = {‘alex‘:False}
# def login(func):   # manager
#     def inner(name):
#         if login_info[name] != True:
#             user = input(‘user :‘)
#             pwd = input(‘pwd :‘)
#             if user == ‘alex‘ and pwd == ‘alex3714‘:
#                 login_info[name] = True
#         if login_info[name] == True:
#             ret = func(name)     # timmer中的inner
#             return ret
#     return inner
#
# def timmer(f):
#     def inner(*args,**kwargs):
#         start_time = time.time()
#         ret = f(*args,**kwargs)     # 调用被装饰的方法
#         end_time = time.time()      #
#         print(end_time - start_time)
#         return ret
#     return inner
#
# @login
# @timmer
# def index(name):
#     print(‘欢迎%s来到博客园首页~‘%name)
#
# @login
# @timmer    # manager = login(manager)
# def manager(name):
#     print(‘欢迎%s来到博客园管理页~‘%name)
#
# index(‘alex‘)
# index(‘alex‘)
# manager(‘alex‘)
# manager(‘alex‘)

2、迭代器和生成器:

  2.1、可迭代、迭代器:(Iterable,Iterator)

    可迭代:可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法(凡是可以使用for循环取值的都是可迭代的

      可迭代的类型:列表 字典 元组 字符串 集合 range 文件句柄 enumerate

    迭代器:迭代器 = iter(可迭代的)或者li.__iter__(),自带一个__next__方法

l = [1,2,3]
# lst_iter = iter(l)   # l.__iter__()
# while True:
#     try:
#         print(next(lst_iter)) # lst_iter.__next__()
#     except StopIteration:
#         break
# py2 range 不管range多少 会生成一个列表 这个列表将用来存储所有的值
# py3 range 不管range多少 都不会实际的生成任何一个值
# 迭代器的优势:
#     节省内存
#     取一个值就能进行接下来的计算 ,而不需要等到所有的值都计算出来才开始接下来的运算 —— 快
# 迭代器的特性:惰性运算
# f = open()# for line in f:   可迭代的

  2.2、生成器:

    1、自己写的迭代器 就是一个生成器

    2、两种自己写生成器(迭代器)的机制:生成器函数 生成器表达式

    3、简单生成器的写法:(关键字yield)

# 凡是带有yield的函数就是一个生成器函数# def func():#     print(‘****‘)#     yield 1#     print(‘^^^^‘)#     yield 2   # 记录当前所在的位置,等待下一次next来触发函数的状态## g = func() #调用后代码未执行,返回一个生成器(迭代器)# print(‘--‘,next(g))  # print(‘--‘,next(g))# 生成器函数的调用不会触发代码的执行,而是会返回一个生成器(迭代器)# 想要生成器函数执行,需要用next或for
# 使用生成器监听文件输入的例子
# import time
# def listen_file():
#     with open(‘userinfo‘) as f:
#         while True:
#             line = f.readline()
#             if line.strip():
#                 yield line.strip()
#             time.sleep(0.1)
#
# g = listen_file()
# for line in g:
#     print(line)

    4、生成器中的关键字send

# send关键字
# def func():
#     print(11111)
#     ret1 = yield 1   #ret1 接受secd传入进来的值
#     print(22222,‘ret1 :‘ret1)
#     ret2 = yield 2
#     print(33333,‘ret2 :‘,ret2)
#     yield 3
#
# g = func()
# ret = next(g)
# print(ret)
# print(g.send(‘alex‘))  # 在执行next的过程中 传递一个参数 给生成器函数的内部
# print(g.send(‘金老板‘))
# 想生成器中传递值 有一个激活的过程 第一次必须要用next触发这个生成器
# 例子
# 计算移动平均值
# 12 13 15 18
# 月度 的 天平均收入
# def average():
#     sum_money = 0
#     day = 0
#     avg = 0
#     while True:
#         money = yield avg
#         sum_money += money
#         day += 1
#         avg = sum_money/day
#
# g = average()
# next(g)
# print(g.send(200))
# print(g.send(300))
# print(g.send(600))

    5、预激生成器

# def init(func):#     def inner(*args,**kwargs):#         ret = func(*args,**kwargs)#         next(ret)  # 预激活#         return ret#     return inner## @init# def average():#     sum_money = 0#     day = 0#     avg = 0#     while True:#         money = yield avg#         sum_money += money#         day += 1#         avg = sum_money/day## g = average()# print(g.send(200))# print(g.send(300))# print(g.send(600))

    6、yield from

# def generator_func():
#     yield from range(5)
#     yield from ‘hello‘
#     # for i in range(5):
    #     yield i
    # for j in ‘hello‘:
    #     yield j

# g = generator_func()
# for i in generator_func():
#     print(i)

# g1 = generator_func()
# g2 = generator_func()
# next(generator_func())
# next(generator_func())

    7、如何从生成器中取值

# 第一种 :next  随时都可以停止 最后一次会报错
# print(next(g))
# print(next(g))
# 第二种 :for循环 从头到尾遍历一次 不遇到break、return不会停止
# for i in g:
#     print(i)
# 第三种 :list tuple 数据类型的强转  会把所有的数据都加载到内存里 非常的浪费内存
# print(g)
# print(list(g))

    8、特性

# 生成器函数 是我们python程序员实现迭代器的一种手段
# 主要特征是 在函数中 含有yield
# 调用一个生成器函数 不会执行这个函数中的带码 只是会获得一个生成器(迭代器)
# 只有从生成器中取值的时候,才会执行函数内部的带码,且每获取一个数据才执行得到这个数据的带码
# 获取数据的方式包括 next send 循环 数据类型的强制转化
# yield返回值的简便方法,如果本身就是循环一个可迭代的,且要把可迭代数据中的每一个元素都返回 可以用yield from
# 使用send的时候,在生成器创造出来之后需要进行预激,这一步可以使用装饰器完成
# 生成器的特点 : 节省内存 惰性运算
# 生成器用来解决 内存问题 和程序功能之间的解耦

3、列表推倒式

# new_lst = []
# for i in range(10):
#     new_lst.append(i**2)
# print(new_lst)
# print([i**2 for i in range(10)])
# l = [1,2,3,-5,6,20,-7]
# print([i%2 for i in range(10)])
# l = [1,2,3,-5,6,20,-7]
# print([num for num in l if num%2 == 1])

# 30以内所有能被3整除的数
# print([i for i in range(30) if i%3 ==0])
#
# 30以内所有能被3整除的数的平方
# print([i**2 for i in range(30) if i%3 ==0])

# 找到嵌套列表中名字含有两个‘e’的所有名字
# names = [[‘Tom‘, ‘Billy‘, ‘Jefferson‘, ‘Andrew‘, ‘Wesley‘, ‘Steven‘, ‘Joe‘],
#          [‘Alice‘, ‘Jill‘, ‘Ana‘, ‘Wendy‘, ‘Jennifer‘, ‘Sherry‘, ‘Eva‘]]
# print([name for name_lst in names for name in name_lst if name.count(‘e‘) == 2])

4、生成器表达式:

# l = [i for i in range(30) if i%3 ==0]   # 列表推倒式 排序的时候
# g = (i for i in range(30) if i%3 ==0)   # 生成器表达式 庞大数据量的时候 使用生成器表达式
# print(l)
# print(g)
# for i in g:print(i)

5、内置函数:(总共有68个内置函数)

  

6、匿名函数:

# lambda表达式
# def add(a,b):
#     return a+b
# add = lambda a,b : a+b  传两个参数  : 执行的方法# print(add(1,2))
# # for i in map(func,range(10)):print(i)

# for i in map(lambda num : num ** 2 ,range(10)):print(i)
# def func(num):
#     return num%2
# print(min(-2,3,-4,key=func)) 可以直接执行执行方式

# print(min(-2,3,-4,key=lambda num:num%2))

7、递归函数:


# 递归 就是自己调用自己
# def func():
#     print(1)
#     func()
#
# func()    # 997 /998
# 递归需要有一个停止的条件

# def fn(6):#     if 6 == 1:return 1#     return 6*fn(5)# print(fn(6))

  

 

原文地址:https://www.cnblogs.com/xingguang009/p/8919810.html

时间: 2024-11-08 16:55:09

第四课 函数补充--装饰器、迭代器、生成器、匿名函数、递归函数的相关文章

python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式

本节课重要知识点内容如下: 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式 1.函数嵌套 函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数 def bar(): print('from nbar')def foo(): print('from foo') bar()foo()def max2(x,y): if x > y: return x else: return ydef max4(a,

函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数def max(x,y): if x>y: return x else: return ydef max1(a,b,c,d): res=max(a,b) res2=max(res,c) res3=ma

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

<04day>_函数嵌套--闭包函数--装饰器--迭代器--生成器

一.函数的嵌套定义 1.python函数支持嵌套 def f1(): #f1函数的定义 def f2(): #f2函数的定义 print('from f2') def f3(): #f3函数的定义 print('from f3') f2() f1() 嵌套函数--运行结果说明: 1首先调用f1()结果,f1函数为空.担保函f2函数,f2函数有内容打印并且有调用,f2函数包含f3函数,但f3函数无调用. 运行结果: 列子:多个数据之间的大小比较. #!/usr/bin/python # -*- c

python学习笔记4:高阶函数,装饰器,生成器,迭代器

一.高级函数1.把一个函数名当作实参传给另一个函数2.返回值包含函数名>>> def bar():... print ("in the bar")... >>> def foo(func):... res=func()... return res... >>> foo(bar)in the bar 二.嵌套函数在函数中定义另一个函数 三.装饰器装饰器本质上是函数,作用是装饰其他函数,就是为其他函数添加附加功能.原则1:不能修改被装饰

五、python函数、装饰器、内置函数、json及模块

一.递归调用 1.一个函数自己调用自己就是递归调用,最多一个函数递归调用自己999次,超过就会出错2.递归必须有一个明确的结束条件3.每次进入更深一层递归时,问题规模相比上次递归都应有所减少4.递归效率不高,少用递归 eg:def test1(): num = int(input('please enter a number:')) if num%2==0:#判断输入的数字是不是偶数 return True #如果是偶数的话,程序就退出了,返回true print('不是偶数请重新输入!') r

函数篇 ---> 装饰器与内置函数

装饰器: 从名字上来看,装饰器就是用来装饰内容的一个工具.本质上是一个闭包 在开发中,装饰器必须要遵守开放封闭原则:对扩展开放,对修改源代码封闭. 在装饰器中,有一个很重要的工具就是@,称之为语法糖,语法糖的本质就是:被装饰的函数名 = 装饰器的名字(被装饰的函数名) 在装饰器的应用上,有一个很简单的例子 计算简易的函数运行时间 import time # 导入time模块 print(time.time()) # 获取时间戳 start_time = time.time() # 开始时间 de

函数对象,函数的嵌套,名称空间与作用域,闭包,装饰器,迭代器,内置函数

一,函数对象 函数对象:函数是第一类对象,即函数可以当做数据传递 1,可以被引用 2,可以做参数的传递 3,返回值可以是函数 4,可以当作容器类型的元素 二,函数嵌套 1,函数的嵌套调用 2,函数的嵌套定义 三,名称空间与作用域 名称空间:存放名字的地方叫名称空间,存放这些值与名字的绑定关系 查看内置名称的两种方法: 三种名称空间 1,内置名称空间:随着python解释器的启动而产生 2,全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入该空间 3,局部名称空间:调用函