python基础知识之装饰器

一,装饰器(decorator)。(day4.3)

装饰器:本质是函数,(装饰其他函数)就是为其他函数添加附加功能。

#可以达成的作用# 原则1:不能修改被装饰的函数的源代码。(改源代码有可能会造成未知的错误,因为你不知道有些地方是怎么样调用此函数的)

#可以达成的作用# 原则2:不能修改被修饰的函数的调用方式。(即,不对原函数照成任何影响)

1.实现装饰器的知识储备:

1.函数即”变量“。

2.高阶函数。

3.嵌套函数。

高阶函数+嵌套函数=装饰器

===》》》1.函数即“变量”(要重点理解这个) 

a).内存存储回收机制(解释器源代码可知其底层实现方式)==》》D4.5.-+11:54

  若没有变量名/函数名也就是说没有地方引用这边内存,在解释器刷新的时候这片内存则会被回收。

b)函数在内存里的存放机制是:(仅仅写一个函数名则相当于这个函数体所占用的内存地址,而内存地址加上小括号则相当于运行这个内存地址里的”东西“

可以理解为()就是执行这个它前面的内存地址里的东西的执行动作

#实例
#return 后的值是函数运行完成后返回到开始运行处的“东西”
import time def bar(): time.sleep(0.5) print("in the bar") return 123 print(bar()) t = bar print(bar) t()

用函数名即def后的为“门牌号”找到一个内存地址再将函数体存入这个内存中。等待使用这个门牌号(即函数名)来调用他对应的内存里的函数体来执行。

 ===》》》2.高阶函数:

  a)把一个函数名当实参传给另一个函数。(可实现,在不修改被装饰的函数的源代码情况下为其添加功能)

   

#高阶函数的a)功能实例。
import time
def bar():
  time.sleep(3)
  print("in the bar")
def funt1(funt):
  # start_time = time.time()
    print('hello world!')
    return funt
bar = funt1(bar)
bar()

  b)返回值中包含函数名。(不修改被修饰的函数的调用方式,对原函数添加了功能。

import time
def bar():
    time.sleep(0.5)
    print("in the bar")

# def test2(name):
#     print(name)
#     return name
# print(test2(bar))

def time1(funt):
    start_time = time.time()
    funt()
    end_time = time.time()
    print('该程序运行时间是:%s'%(start_time-end_time))
    return funt
bar = time1(bar)
bar() #不修改被修饰的函数的调用方式,对原函数添加了功能。

 ===》》》3.嵌套函数。

函数里套一个被定义的函数

#实例
def test1():
    print("AAA")
    def test2():#嵌套函数只能在这个局部语句块里使用,函数即变量和局部变量同理。
      pass
#下面的实例可以演示函数的局部性
def test1():
    x = 'h'
    def test2():
        x = 'h1'
        def test3():
            x ='h2'
            print(x)
        test3()
    test2()
test1()
》》》h2
def test1():
    x = 'h'
    def test2():
        x = 'h1'
        def test3():
            # x ='h2'
            print(x)
        test3()
    test2()
test1()
》》》h1
def test1():
    x = 'h'
    def test2():
        # x = 'h1'
        def test3():
            # x ='h2'
            print(x)
        test3()
    test2()
test1()
》》》h

 2.最简单的装饰器实例:

def timer(func):
    def deco():
        import time
        start_time=time.time()
        func()
        stop_time=time.time()
        print('the func run time is %s'%(start_time-stop_time))
    return deco
def test():
    import time
    print('start')
    time.sleep(1)
    print('stop')

test()

》》》start
   stop

test=timer(test)

test()

》》》start
stop
the func run time is -1.0072598457336426

小节:装饰器是在被装饰的函数头加上@timer即相当于 在使用的时候写了一个test=timer(test)

def timer(func):
    def deco():
        import time
        start_time=time.time()
        func()
        stop_time=time.time()
        print('the func run time is %s'%(start_time-stop_time))
    return deco
@timer
def test():
    import time
    print('start')
    time.sleep(1)
    print('stop')

test()

》》》 start
stop
the func run time is -1.0072598457336426

3.装饰器升级,可以修饰随便几个参数的函数,并且可以返回被装饰函数的返回值。

def timer(func):
    def deco(*args,**kwargs): #修饰随便几个参数的函数
        import time
        start_time=time.time()
        ret=func(*args,**kwargs) #修饰随便几个参数的函数
        stop_time=time.time()
        print('the func run time is %s'%(start_time-stop_time))

  return ret #返回被装饰函数的返回值

    return deco
@timer
def test():
    import time
    print('start')
    time.sleep(1)
    print('stop')
@timer #相当于加了一条test1=timer(test1)
def test1(name,age):
    print('123',name,age)

test()
test1(123,22)  

4.最终完整版,装饰器。(包含了说明)#51cto博客有相关内容#

# Author:979
# blog addr:http://www.cnblogs.com/home979/
user ="zsw"
code ="123"
def auth(aut_type):
    #print(aut_type)#可以了解传入装饰器的aut_type参数是什么量
    def choice(func):
        #print(func)#可以了解传入装饰器的func参数是什么量
        def yanzhen(*args,**kwargs):
            #print(*args,**kwargs)#可以了解传入装饰器的*args,**kwargs参数是什么量
            if aut_type =='local':#这一句是装饰器type:local的具体功能
                username = input("username:")
                password = input("password:")
                if user == username and code == password:
                    print("waiting")
                    # ret = func(*args,**kwargs) #这样的话可以得到func的返回值 并且可以继续运行
                    # return ret #直接用这样一句就可以返回开始得到func的返回值
                    return func(*args,**kwargs) #可用上面两句替换,这一句必须加
                else:
                    print("Invalid username or password")
                    
            elif aut_type =='ldap':#这一句是装饰器type:ldap的具体功能
                print("不会弄ldap,搞毛线啊")
        return yanzhen#返回yanzhen的物理地址
    return choice #返回choice的物理地址
#下面是具体被调用装饰器的函数实例
def index():
    print("welcom to index")
    
@auth(aut_type='local')
def home(bankuai):
    if bankuai =='home':
        print("welcom to home A")
    else:
        print("welcom to home B")
    return "from 123"

@auth(aut_type='ldap')
def bbs():
    print("welcom to bbs")

index()
print(home('home'))
bbs()

二,匿名函数: 

没有def申明函数名字。

例如: 匿名函数

lambda n:print(n)

相对于

def dayin(n):

  print(n)

这个函数

  

原文地址:https://www.cnblogs.com/home979/p/7880651.html