python基础之装饰器

一 什么是装饰器

器即函数

装饰即修饰,意指为其他函数添加新功能

装饰器定义:本质就是函数,功能是为其他函数添加新功能 #装饰器本身就是函数,被装饰的也是函数。

 

为什么要用装饰器:

 1.不修改被装饰函数的源代码(开放封闭原则);

 2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式。

代码上线后,就是为了尽量避免修改,不修改原函数的源代码和调用方式。 # 函数及定义和使用。

装饰器语法:

在被装饰上的正上方写一个@,它会把@这一行下面这一行的函数传递到函数里,再重新赋值给index。

func就是index函数,print(func)返回得是index内存地址。

二 装饰器需要遵循的原则

1.不修改被装饰函数的源代码(开放封闭原则)

2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式

(1)无参装饰器:

不用传参数来使用装饰器。

  以下的操作是为函数foo来增加新的计时功能:不改变原函数的代码和调用方式

import time #调用time模块
 
def timmer(func): #装饰器timmer,将函数foo的函数名为参数传给timmer
    def wrapper():#嵌套函数
        start_time = time.time()#开始时间
        func() #func=函数foo的内存地址加括号函数是可以直接被调用的
        stop_time = time.time() #结束时间
        print("函数运行的时间是%s"%(stop_time-start_time))
    return wrapper #返回wrapperde 值
 
@timmer #装饰器的语法@+装饰器名,foo = timmer(foo)
def foo(): #定义的一个无参函数
    time.sleep(2) #使程序睡眠2s
    print("welcome to beijing")
 
foo() #调用foo函数
---------------------以下是输出结果----------------------
    welcome to beijing
    函数运行的时间是2.0

(2)

要传参数来使用装饰器。

  以下的操作是为函数my_max来增加新的计时功能:不改变原函数的代码和调用方式

import time #调用time模块
 
def timmer(func): #嵌套函数
    def wrapper(*args,**kwargs):#接收参数
        start_time = time.time() #开始计时
        func(*args,**kwargs) #通过内存地址加括号里接收的参数来调用函数
        stop_time = time.time() #结束计时
        print("函数的运行时间是%s"%(stop_time-start_time))
    return wrapper #返回wrapper的值
 
@timmer #my_max=timmer(my_max)#为my_max这个函数增加计时功能
def my_max(x,y): #比较两个数的大小
    time.sleep(3) #睡眠3s,方便实验效果
    res = x if x > y else y #判断x与y的大小
    print("from the my_max,the max is %s"%res)
 
my_max(1,2) #调用函数并按位置传参
---------------------以下是输出结果-----------------------
    from the my_max,the max is 2
    函数的运行时间是3.0

 

三 实现装饰器知识储备

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

四 高阶函数

高阶函数定义:
1.函数接收的参数是一个函数名

2.函数的返回值是一个函数名

3.满足上述条件任意一个,都可称之为高阶函数

def foo():
    print('我的函数名作为参数传给高阶函数')
def gao_jie1(func):
    print('我就是高阶函数1,我接收的参数名是%s' %func)
    func()

def gao_jie2(func):
    print('我就是高阶函数2,我的返回值是%s' %func)
    return func

gao_jie1(foo)
gao_jie2(foo)

高阶函数示范
高阶函数示范
#高阶函数应用1:把函数当做参数传给高阶函数
import time
def foo():
    print('from the foo')

def timmer(func):
    start_time=time.time()
    func()
    stop_time=time.time()
    print('函数%s 运行时间是%s' %(func,stop_time-start_time))
timmer(foo)
#总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式

把函数当做参数传给高阶函数
把函数当作高阶函数传给参数
#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
import time
def foo():
    print('from the foo')

def timmer(func):
    start_time=time.time()
    return func
    stop_time=time.time()
    print('函数%s 运行时间是%s' %(func,stop_time-start_time))
foo=timmer(foo)
foo()
#总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能

函数返回值是函数名
函数返回值是函数名

高阶函数总结
1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式
2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能

五 函数嵌套

def father(name):
    print('from father %s' %name)
    def son():
        print('from son')
        def grandson():
            print('from grandson')
        grandson()
    son()

father('林海峰')

六 闭包

'''
闭包:在一个作用域里放入定义变量,相当于打了一个包
'''
def father(name):
    def son():
        # name='alex'
        print('我爸爸是 [%s]' %name)
        def grandson():
            # name='wupeiqi'
            print('我爷爷是 [%s]' %name)
        grandson()
    son()

father('林海峰')

七 无参装饰器

装饰器举例

无参装饰器1运行结果

无参装饰器2无参装饰器3

有参装饰器

#为什么要用装饰器及开放封闭原则

#什么是装饰器
# import time
# def timmer(func):
#     def wrapper(*args,**kwargs):
#         start=time.time()
#         res=func(*args,**kwargs)
#         stop=time.time()
#         print('run time is %s ' %(stop-start))
#     return wrapper
#
#
# @timmer
# def index():
#     time.sleep(3)
#     print('welcome to oldboy')
#
# index()





#装饰器
# import time
#
# @名字     #home=名字(home)
# def home():
#     time.sleep(3)
#     print('welcome to oldboy')
#
# index()


# def get(url):
#     def index():
#         return urlopen(url).read()
#     return index


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


# index=timmer(index)
@timmer
def index():
    time.sleep(3)
    print('welcome to oldboy')

@timmer
def home(name):
    time.sleep(2)
    print('welcome to %s home page' %name)

# def my_max(x,y):
#     print('from my_max func')
#     return x+y

# index()  #--=--->wrapper()
home('dragon')
无参装饰器1
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs) #home(name)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
    return wrapper

@timmer #home=timmer(home)
def home(name):
    time.sleep(2)
    print('welcome to %s home page' %name)




@timmer  #auth=timmer(auth)
def auth(name,password):
    print(name,password)

@timmer
def tell():
    print('-=----------')
home('dragon')  #wrapper('dragon')
auth('egon','123') #wrapper('egon','123')
tell()
无参装饰器2
import time
def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)  #my_max(1,2)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper


@timmer
def my_max(x,y):
    print('my_max function')
    res=x if x > y else y
    return res

res=my_max(1,2) #res=wrapper(1,2)
print('=====>',res)
无参装饰器3
def auth2(auth_type):
    def auth(func):
        # print(auth_type)
        def wrapper(*args,**kwargs):
            if auth_type == 'file':
                name=input('username: ')
                password=input('password: ')
                if name == 'zhejiangF4' and password == 'sb945':
                    print('auth successfull')
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('auth error')
            elif auth_type == 'sql':
                print('还他妈不会玩')
        return wrapper
    return auth

@auth2(auth_type='sql') #@auth  #index=auth(index)
def index():
    print('welcome to inex page')

# @auth
# def home():
#     print('welcome to home page')
index()
有参装饰器
def auth2(auth_type): #1 #3
    def auth(func): #4 #6
        def wrapper(*args,**kwargs): #7 #10
            if auth_type == 'file': #11
                name=input('username: ')
                password=input('password: ')
                if name == 'zhejiangF4' and password == 'sb945':
                    print('auth successfull')
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('auth error')
            elif auth_type == 'sql': #12
                print('还他妈不会玩') #13
        return wrapper #8
    return auth #5

@auth2(auth_type='sql') #2
def index():
    print('welcome to inex page')

# @auth
# def home():
#     print('welcome to home page')
index() #9
装饰器执行流程
# @aaa
# def func():
#     pass
#
#
# func=aaa(func)

# @ccc
# @bbb
# @aaa
# def func():
#     pass
#
# func=ccc(bbb(aaa(func)))


#
# @ccc('c')
# @bbb('b')
# @aaa('a')
# def func():
#     pass
#
# func=ccc('c')(bbb('b')(aaa('a')(func)))
装饰器补充
import time
current_login={'name':None,'login':False}

def timmer(func):
    def wrapper(*args,**kwargs):
        start_time=time.time()
        res=func(*args,**kwargs)  #my_max(1,2)
        stop_time=time.time()
        print('run time is %s' %(stop_time-start_time))
        return res
    return wrapper

def auth2(auth_type='file'):
    def auth(func):
        # print(auth_type)
        def wrapper(*args,**kwargs):
            if current_login['name'] and current_login['login']:
                res=func(*args,**kwargs)
                return res
            if auth_type == 'file':
                name=input('username: ')
                password=input('password: ')
                if name == 'zhejiangF4' and password == 'sb945':
                    print('auth successfull')
                    res=func(*args,**kwargs)
                    current_login['name']=name
                    current_login['login']=True
                    return res
                else:
                    print('auth error')
            elif auth_type == 'sql':
                print('还他妈不会玩')
        return wrapper
    return auth

@timmer
@auth2(auth_type='file') #@auth  #index=auth(index)
def index():
    print('welcome to inex page')

@auth2()
def home():
    print('welcome to home page')



#调用阶段
index()
home()
多个装饰器

 

posted on 2017-04-10 11:57  bigdata_devops  阅读(291)  评论(0编辑  收藏  举报

导航