python语法基础-函数-装饰器-长期维护

###############    装饰器的初成和开放封闭原则    ##############

# 装饰器
# 装饰器非常重要,面试Python的公司必问,
# 原则:开放封闭原则
#

# 需求:计算程序执行的时间,
import time
def func():
    start = time.time()
    time.sleep(0.01)
    print(123)
    end = time.time()
    print(end-start)

func()

# 这种写法如果有100个函数,你都要加一遍这是不行的,太麻烦了,
# 第二版

def func():
    time.sleep(0.01)
    print(123)

def timer(f):
    start = time.time()
    f()
    end = time.time()
    print(end-start)

timer(func)  # 专门写了一个函数用来计算函数的执行时间,

# 闭包的写法

def func():
    time.sleep(0.01)
    print(123)
def timer(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print(end-start)
    return inner

# 这就是一个闭包,因为是函数的嵌套,并且函数内部调用函数外部的参数,
# 不修改函数的调用方式,还想要在函数的前后添加功能,
# timer就是一个装饰器,对函数有装饰作用,
func = timer(func)  # inner
func()  # inner()

# 开放封闭原则,适用于对已经固定的额功能,和源码,这个原则是为了程序的稳定性,
# 开放就是对已经有的功能的拓展是开放的,
# 封闭就是对已经有的功能是不改动的,

# 所以使用装饰器是一个非常不错的方式在不改变程序内部的情况下,在程序的前后添加功能,

###############    最终的装饰器版本    ##############

# 最终的装饰器版本
# 解决两个问题,
# 1是被装饰函数有返回值
# 2是被装饰函数有参数

import time
def timer(f):
    def inner(*args,**kwargs):  # 这个参数就是为了能接收被装饰器函数的参数,
        start = time.time()
        ret = f(*args,**kwargs)
        end = time.time()
        print(end-start)
        return ret  # 这个地方要返回是因为被装饰函数可能会有返回值,
    return inner

@timer
def func(a):
    time.sleep(0.01)
    print(123)
    print(a)
    return 123
# func = timer(func)  # inner
ret = func(1)  # inner(),这个地方已经是调用的inner了,所以一定要在inner中把被装饰函数的返回值返回回来,
print(ret)

# def outer():
#     def inner():
#         return 123
#     inner()
#
# outer()  # 这个调用是不会有返回值的,因为你只调用了没有返回值,

# 所有有一个装饰器的固定模式
from functools import wraps
def outer(func):  # 或者叫做wrapper,这就是装饰器的意思,一般会起一个和业务相关的名字,
    @wraps(func)  # 加上这一句,再去打印函数的name的时候,就不会是inner了,
    def inner(*args,**kwargs):  # 一般就是一个inner
        # 在被装饰函数之前写的东西
        ret = func(*args,**kwargs)
        # 在被装饰函数之后写的东西
        return ret
    return inner

@outer  # 这一句就是test=outer(test)
def test():
    """
    函数测试,
    :return:
    """
    print(123)

test()  # 这个地方就是inner()了,
print(test.__name__)  # 这个被装饰器装饰了之后会有问题,inner返回的是inner,而不是test
print(test.__doc__)

###############    装饰器进阶--带参数的装饰器    ##############

"""

装饰器进阶
1,带参数的装饰器

场景:就是我写了一个计算代码执行时间的装饰器,然后给每一个函数加上了装饰器,
如果我想要去掉装饰器的时候,就需要一个一个的去掉了,我想要用的时候还需要再一个一个的加上,很麻烦,有什么好的办法?

解决方法:就是给装饰器加上一个参数,然后通过控制参数来判断是否开启装饰器,
参数就叫做flag,
这种代码实现就是使用三层装饰器,这样只需要控制flag就可以控制装饰器是否开启了,

"""

import time

flag = False
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start = time.time()
                ret = func(*args,**kwargs)
                end = time.time()
                print(end-start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer

@timmer_out(flag)
def test1():
    time.sleep(1)
    print(123)

@timmer_out(flag)
def test2():
    time.sleep(1)
    print(123)

# @timmer:这一句还好理解就是func=timmer(func)
# @timmer_out(flag):为了传递参数,我们可以再次在装饰器外部加一层,用来传递参数,
# 这一句要分开看了,第一步是timmer_out(flag),然后返回了timmer,第二步才是@timmer,执行装饰器,

test1()
test2()

###############   装饰器进阶---多个装饰器装饰一个函数    ##############

"""
装饰器进阶:
2,多个装饰器装饰一个函数,

"""
def wrapper1(func):
    def inner():
        print(‘wrapper1 ,before func‘)
        func()
        print(‘wrapper1 ,after func‘)
    return inner

def wrapper2(func):
    def inner():
        print(‘wrapper2 ,before func‘)
        func()
        print(‘wrapper2 ,after func‘)
    return inner

@wrapper2
@wrapper1
def f():
    print(‘in f‘)

f()
"""
执行结果:
wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func
说明了几个问题:
1,多个装饰器是把函数之前的装饰代码都执行之后,然后才是执行被装饰函数,最后是函数之后的装饰代码
2,函数之前的执行顺序是谁在上面执行谁,这是从上到下,函数之后的执行顺序是谁在下面执行谁,这是从下往上,
就像是俄罗斯套娃,进的时候从外往里,出的时候从里往外,
"""

原文地址:https://www.cnblogs.com/andy0816/p/12289724.html

时间: 2024-10-08 19:35:07

python语法基础-函数-装饰器-长期维护的相关文章

python入门基础-函数装饰器的理解

1.装饰器 # 知乎某大神是这么比喻装饰器的:内裤可以用来遮羞,但是到了冬天他就没有办法为我们御寒,聪明的人于是发明了长裤,有了长裤后宝宝再也不冷了, # 装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效. # # 大神是将程序中原本的函数比喻成内裤,而装饰器比喻成了长裤,这样在寒冬里它们结合一起使用就给所有人带来了温暖. # # 装饰器本质上是一个python函数,它可以让其它函数在不改动代码的情况下增加额外的功能,并且装饰器的返回值也是一个函数对象. # 在

python语法基础-并发编程-线程-长期维护

###############   线程和GIL,全局解释器锁    ############## """ 线程 为什么会有进程? 主要是能够同时处理多个任务,多个任务还要进行切换,时间片轮转 为什么会有线程? 进程并不是执行任务的最小单元,每一个进程里面有都一个线程,我们叫做主线程, 早期没有线程,一个进程只能干一个任务,如果有多个任务,只能多起进程,进程太多不行的, 进程内部的内存是共享的,所以需要线程,否则还要涉及到进程间的通信,这比较浪费资源 所以线程的出现解决了两个

python语法基础-并发编程-进程-长期维护

###############    进程的启动方式1    ############## """ 并发编程: 进程 1,运行中的程序,就是进程,程序是没有生命的实体,运行起来了就有生命了, 操作系统可以管理进程,进程是操作系统基本的执行单元, 2,每一个进程都有它自己的地址空间,进程之间是不会混的,比如qq不能访问微信的地址空间, 操作系统替你隔离开了,这也是操作系统引入进程这个概念的原因, ####################################### 进

Python作用域-->闭包函数-->装饰器

1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部定义的变量 b.在局部能够访问到全局定义的变量,但是不能修改全局定义的变量(当然有方法可以修改) 下面我们来看看下面实例: x = 1 def funx(): x = 10 print(x) # 打印出10 funx() print(x) # 打印出1 如果局部没有定义变量x,那么函数内部会从内往外

python 内置函数 装饰器

一.内置函数 1.compile compile(source, filename, mode[, flags[, dont_inherit]]) 用来编译一段字符串的源码,结果可以生成字节码或者AST(抽像语法树),字节码可以使用函数exec()来执行,而AST可以使用eval()来继续编译. >>> str = "for i in range(0,10): print(i)" >>> c = compile(str,'','exec') >

python之闭包函数 装饰器 作业

一:编写函数,(函数执行的时间是随机的) import randomdef t(): time.sleep(random.randrange(1,3)) print('hello')二:编写装饰器,为函数加上统计时间的功能 import timeimport randomdef timebe(func): def wrapper(*args,**kwargs): start_time=time.time() res = func(*args, **kwargs) end_time=time.ti

python语法基础-函数-长期维护

###############    函数的定义调用,返回值和返回值接收    ############## def mylen(): s = "myname" i = 0 for item in s: i += 1 return i def func(): return {"name":"andy"},[1,2,3] l = mylen() print(func()) # 从这个例子可以学到几个:函数的定义,函数的调用,函数的返回值, # 关于

python语法基础-函数-进阶-长期维护

###############    函数的命名空间和作用域    ############## """ # 函数进阶 命名空间和作用域 命名空间 全局命名空间——我们自己写的非函数中的代码 是在程序从上到下被执行的过程中依次加载进内存的, 放置了我们设置的所有的变量名和函数名, 局部命名空间,——函数 就是函数内部定义的名字 在函数调用的时候才会产生这个命名空间,随着函数调用的结束,这个命名空间就消失了, 内置命名空间,——Python解释器, 就是Python解释器一启动

Python-12:Python语法基础-函数

1.函数 function,通俗来讲函数就是功能,函数是用来封装功能的,函数分为两种类型,一种是系统自带的不用我们编写就可以使用的.另一种函数是自定义的,需要我们编写其功能,这种函数自由度高,叫做自定义函数. #encoding:utf-8 #系统自带的函数 #实现取字符串长度的功能 a="hello,jiyongxin" print len(a) #15 #实现字符串的切割 a="student" b=a.split("u") print b