【python】-- 装饰器、迭代器、生成器

装饰器

装饰器本质是函数,是用来装饰其他函数,顾名思义就是,为其他的函数添加附件功能的。

一、装饰器原则:

  1. 不能修改被装饰函数的源代码
  2. 不能修改被装饰函数的调用方式

def logging():
    print("logging...")

#正确写法,没有修改源码
def test1():
    pass

#错误写法,不能修改源码
def test1():
    pass
    logging()

# 调用方式,也不能被修改
test1()

二、装饰器知识:

  1. 函数即"变量"
  2. 高阶函数+嵌套函数 =》装饰器

1、函数即”变量“

python的内存机制,看如下代码:

#变量
x = 1
#函数
def test():
    pass

在内存图中是这样表示的:

x、test 是变量名,保存在栈内存中,1、函数体  保存在堆内存中

2、高阶函数+嵌套函数 =》装饰器

装饰器实现过程:

第一步:原始代码

def home():
    print("---首页----")

def TV():
    print("----TV----")

def music()
    print("---music-----")

第二步:想给部分模块加个登陆认证

user_status = False #用户登录了就把这个改成True

def login():
    _username = "ABC" #假装这是DB里存的用户信息
    _password = "12345" #假装这是DB里存的用户信息
    global user_status

    if user_status == False:
        username = input("user:")
        password = input("pasword:")

        if username == _username and password == _password:
            print("welcome login....")
            user_status = True
        else:
            print("wrong username or password!")
    else:
        print("用户已登录,验证通过...")

def home():
    print("---首页----")

def TV():
    login() #执行前加上验证
    print("----TV----")

def music():
    print("----music----")

虽然这样实现了认证功能,但是修改了被装饰函数的源代码,违背了装饰器的原则”不能修改被装饰函数的源代码“

第三步:代码改进,使用高阶函数理念,把函数名当参数传递给认证函数login,这样可以不修改被装饰函数源代码的情况下完成登陆认证

user_status = False #用户登录了就把这个改成True

def login(func):
    _username = "ABC" #假装这是DB里存的用户信息
    _password = "12345" #假装这是DB里存的用户信息
    global user_status

    if user_status == False:
        username = input("user:")
        password = input("pasword:")

        if username == _username and password == _password:
            print("welcome login....")
            user_status = True
        else:
            print("wrong username or password!")
    if user_status == True:
        print("用户已登录,验证通过...")
        func() #只要验证通过了,就调用相应功能 

def home():
    print("---首页----")

def TV():
    print("----TV----")

def music():
    print("----music----")  

login(TV) #需要验证就调用 login,把需要验证的功能 当做一个参数传给login  

虽然这样可以不修改被装饰函数源代码的情况下完成登陆认证,但是违背了装饰器原则”修改了被装饰函数的调用方式“,本来被装饰函数只需要TV()就可调用,现在变成了login(TV)

第四步:代码改进,使用匿名函数理念,将login(TV)变成 TV = login(TV) ,将函数当成值,赋值给变量名TV,跟关键字def 重新定义了TV是一样的效果,不过这样还有一个问题, TV = login(TV)这个赋值过程中,就把

函数TV给调用了,用户自己还没有调用,就自己自动调用肯定是不对的,这个时候需要用到嵌套函数的理念了,在认证函数login里面的再定义一个新函数login_inner,在login函数return(返回)login_inner函数名(对是return login_inner, 不是return  login_inner(), 因为return 函数名 返回的是函数在栈内容的内存地址,return 函数名+() 返回的是该函数的执行结果) 这样在TV = login(TV)赋值的时候,TV赋值的就不是 login(TV)的执行结果了,赋值的值是login_inner的内存地址,等用户再调用的时候 就是TV(),这样就没有改变被装饰函数的调用方式了。

装饰器装饰没有参数函数:

import time

#定义装饰器函数
def timmer(func):  # 把test1这个函数名作为参数传递进来 func=test1
    #定义装饰器中的内置函数
    def deco():
        start_time = time.time()
        func()   #相当于运行test1()
        stop_time = time.time()
        print("the func run time is %s"%(stop_time-start_time))

    return deco

#装饰test1函数
@timmer  # 相当于test1 = timmer(test1)
def test1():
    time.sleep(3)
    print("in the test1")

#直接执行test1函数
test1()

#输出
in the test1
the func run time is 3.0002999305725098
时间: 2024-10-12 03:08:31

【python】-- 装饰器、迭代器、生成器的相关文章

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

函数嵌套名称空间与作用域闭包函数装饰器迭代器生成器三元表达式,列表解析,生成器表达式递归与二分法内置函数--------------------------------------------函数的嵌套调用:在调用一个函数的过程中,又调用了其他函数函数的嵌套定义:在一个函数的内部,又定义另外一个函数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_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,

python第四天装饰器+迭代器+生成器

1.函数嵌套:在调用一个函数的过程中,调用了其他函数 def f1(): x=1 def f2(): print('from f2') f2() f1()  2.名称空间与作用域 a. 名称空间:存放名字与变量值绑定关系的地方 (1)内置名称空间:在python解释器启动时产生,存放一些python内置的名字 (2)全局名称空间:在执行文件时产生,存放文件级别定义的名字. (3)局部名称空间:在执行过程中,如果调用了该函数则会产生该函数的局部名称空间.在调用该函数的时候生效,调用结束时失效 加载

Python学习---装饰器/迭代器/生成器的学习【all】

Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210 原文地址:https://www.cnblogs.com/ftl1012/p/9484145.html

python 装饰器、生成器、迭代器

装饰器 作用:为其他函数增加功能 装饰器必须要明白以下几点: 1.作用域 2.高阶函数 3.闭包 from functools import reduce import time def outside(func): def inside(*args): start = time.time() func(*args) end = time.time() result = end - start print(result) return inside @outside #同于 add = outs

<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

函数+装饰器+迭代器+生成器

闭包函数 闭包:定义在内网函数,包含对外部作用域而非全局作用域 范围:一个函数套用1或n个函数 from urllib.request import urlopen #urlopen模块 作用:爬网页 #闭包函数,内部get函数调用外部page函数 def page(url): #调用url def get(): #下载 return urlopen(url).read() #爬网页 return get #返回url值 baidu=page("http://www.baidu.com"

Day4 装饰器——迭代器——生成器

一 装饰器 1.1 函数对象 一 函数是第一类对象,即函数可以当作数据传递 #1 可以被引用 #2 可以当作参数传递 #3 返回值可以是函数 #3 可以当作容器类型的元素 二 利用该特性,优雅的取代多分支的if def foo(): print('foo') def bar(): print('bar') dic={ 'foo':foo, 'bar':bar, } while True: choice=input('>>: ').strip() if choice in dic: dic[ch

day-5 装饰器 迭代器 生成器

1.装饰器 1.1 带参数的装饰器 参数可以用来决定是否执行某个装饰器的某一部分 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

python_装饰器——迭代器——生成器

一.装饰器 1.什么是装饰器? 器=>工具,装饰=>增加功能 1.不修改源代码 2.不修改调用方式 装饰器是在遵循1和2原则的基础上为被装饰对象增加功能的工具 2.实现无参装饰器 1.无参装饰器的模板 def outter(func): def wrapper(*args,**kwargs): res=func(*args,**kwargs) return res return wrapper 2.使用:在被装饰对象正上方单独一行 @无参装饰器名 def foo(): pass 3.实现有参装