python 装饰器demo

 

  1. 本质就是一个函数,这个函数符合闭包语法结构,可以在函数不需要改变任何代码情况下增加额外功装饰器的返回值是一个函数的引用
  2. 功能:1.引入日志;2.函数执行时间统计;3.执行函数前预备处理;4.执行函数后清理功能;5.权限校验;6.缓存

作用域

x = 1
def funx():
    x = 10
    print(x)
funx()
print(x)


x = 1
def funx():
    print(x)
funx()
print(x) 



x = 1
def funx():
    def func1():
        print(x)
    func1()
funx()
print(x) 

输出

10
1
1
1
1
1

 

 

函数名作为返回值

def outer():
    def inner():
        pass
    return inner

s = outer()
print(s)

输出

<function outer.<locals>.inner at 0x1058c60d0>

 

 

函数名可以作为一个参数

def index():
    print("index func")

def outer(index):
    s = index
    s()

outer(index)

输出

index func

 

 

code 

def outer():
    def inner():
        print("inner func excuted")
    inner()  # 调用执行inner()函数
    print("outer func excuted")
outer()  # 调用执行outer函数

输出

inner func excuted
outer func excuted

 

 

code

x = 1
def outer():

    def inner():
        print("x=%s" %x)  # 引用了一个非inner函数内部的变量
        print("inner func excuted")
    inner()  # 执行inner函数
    print("outer func excuted")

outer()

输出

x=1
inner func excuted
outer func excuted

 

 

code

def outer():
    x = 1
    def inner():
        print("x=%s" % x)
        print("inner func excuted")
    print("outer func excuted")
    return inner  # 返回内部函数名
outer()()

输出

outer func excuted
x=1
inner func excuted

 

 

def outer():
    x = 1
    def inner():
        print("x=%s" %x)
        print("inner func excuted")
    inner()
    print("outer func excuted")

outer()

输出

x=1
inner func excuted
outer func excuted

 

 

code

def outer():
    x = 1
    y = 2
    def inner():
        print("x= %s" %x)
        print("y= %s" %y)

    print(inner.__closure__)
    return inner

outer()

输出

(<cell at 0x102d6ea98: int object at 0x1009e0c80>, <cell at 0x102d6ebe8: int object at 0x1009e0ca0>)

 

 

类装饰器

class Foo(object):
    def __init__(self, func):
        self._func = func
    def __call__(self):
        print('class decorator runing')
        self._func()
        print('class decorator ending')

@Foo
def bar():
    print('bar')

bar()

output

class decorator runing
bar
class decorator ending

 

 

类装饰器

class Foo(object):
    def __init__(self):
        pass
    def __call__(self, func):
        def _call(*args, **kw):
            print('class decorator runing')
            return func(*args, **kw)
        return _call

class Bar(object):
    @Foo()
    def bar(self, test, ids):   # bar = Foo()(bar)
        print('bar')

Bar().bar('aa', 'ids')

output

class decorator runing
bar

 

 

装饰器的嵌套

import time
import random
def timmer(func):
    def wrapper():
        start_time = time.time()
        func()
        stop_time =time.time()
        print('run time is %s' %(stop_time - start_time))
    return wrapper

def auth(func):
    def deco():
        name = input('name: ')
        password = input('password: ')
        if name == 'egon' and password == '123':
            print('login successful')
            func()  # wrapper()
        else:
            print('login err')
        print("hahha")
    return deco

@auth  # index = auth(timmer(index))
@timmer  # index = timmer(index)
def index():
    time.sleep(3)
    print('welecome to index page')
index()

输出

name: egon
password: 123
login successful
welecome to index page
run time is 3.005250930786133
hahha

 

 

有参装饰器

import time
def outer(func):  # 将index的地址传递给func
    def inner(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)   # fun = index  即func保存了外部index函数的地址
        end_time = time.time()
        print("运行时间为%s"%(end_time - start_time))
    return inner  # 返回inner的地址

@outer
def dd(a):
    print("haha -> ",a)

dd("xiaoming")

输出

haha ->  xiaoming
运行时间为5.626678466796875e-05

 

 

无参数装饰器

import time, random

def outer(func):  # 将index的地址传递给func
    def inner():
        start_time = time.time()
        func()   # fun = index  即func保存了外部index函数的地址
        end_time = time.time()
        print("运行时间为%s"%(end_time - start_time))
    return inner  # 返回inner的地址

def index():
    time.sleep(random.randrange(1, 5))
    print("welcome to index page")

@outer
def indexone():
    time.sleep(random.randrange(1, 5))
    print("welcome to index page")

index = outer(index)  # 这里返回的是inner的地址,并重新赋值给index
index()

print("\n")

indexone()

输出

welcome to index page
运行时间为4.00538182258606


welcome to index page
运行时间为1.0052530765533447

 

 

有参数装饰器

import time, random

def outer(func):  # 将index的地址传递给func
    def inner(a):
        start_time = time.time()
        func(a)   # fun = index  即func保存了外部index函数的地址
        end_time = time.time()
        print("运行时间为%s"%(end_time - start_time))
    return inner  # 返回inner的地址

def index(b):
    time.sleep(random.randrange(1, 5))
    print("welcome to index page",b)

@outer
def indexone(a):
    time.sleep(random.randrange(1, 5))
    print("welcome to index page",a)

index = outer(index)  # 这里返回的是inner的地址,并重新赋值给index
index("bb")

print("\n")

indexone("aa")

输出

welcome to index page bb
运行时间为3.0013160705566406


welcome to index page aa
运行时间为4.002547264099121

 

 

被装饰的函数有返回值

import time
import random
def timmer(func):
    def wrapper(*args,**kwargs):
        print("kk")
        print(*args)
        start_time = time.time()
        res=func(*args,**kwargs) #res来接收home函数的返回值
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

@timmer
def home(name):
    time.sleep(random.randrange(1,3))
    print('welecome to %s HOME page' %name)
    return 123123123123123123123123123123123123123123

print(home("haha"))

输出

kk
haha
welecome to haha HOME page
run time is 2.001023054122925
123123123123123123123123123123123123123123

 

 

参考:

https://www.cnblogs.com/huchong/p/7725564.html#_label2

 

 

 

posted @ 2019-07-25 22:49  anobscureretreat  阅读(299)  评论(0编辑  收藏  举报