python函数:装饰器、修正、语法糖、有参装饰器、global与nonlocal

本文目录:

一、装饰器

二、装饰器修正1

三、装饰器修正2

四、装饰器语法糖

五、有参无参装饰器 

六、global与nonloal

 

一、装饰器

 

1 什么是装饰器

器=>工具
    装饰=>指的是为被装饰对象添加新功能

    装饰器本身可以是任意可调用的对象=>函数
    被装饰的对象也可以是任意可调用的对象=>函数

    目标:写一个函数来为另外一个函数添加新功能

2 为何要用装饰器

开放封闭原则: 软件一旦上线就应该对修改封闭,对扩展开放
        对修改封闭:
            1. 不能修改功能的源代码
            2. 也不能修改功能的调用方式

        对扩展开发:
            可以为原有的功能添加新的功能

    装饰器就是要在不修改功能源代码以及调用方式的前提下为原功能添加额外新的功能

3 如何用装饰器

import time

def index():
    print('welcome to index page')
    time.sleep(3)

def outter(func):
    # func=最原始那个index的内存地址
    def wrapper():
        start=time.time()
        func() # 最原始那个index的内存地址()
        stop=time.time()
        print('run time is %s' %(stop-start))
    return wrapper

index=outter(index) #index=outter(最原始那个index的内地址) #index=wrapper函数的内地址
index() #wraper()

 

二、装饰器修正1

import time

def index():
    print('welcome to index page')
    time.sleep(3)
    return 123

#==============================================================
def outter(func):
    # func=最原始那个index的内存地址
    def wrapper():
        start=time.time()
        res=func() # 最原始那个index的内存地址()
        stop=time.time()
        print('run time is %s' %(stop-start))
        return res
    return wrapper

index=outter(index) #index=outter(最原始那个index的内地址) #index=wrapper函数的内地址
#==============================================================

res=index() #res=wraper()
print(res)

 

三、装饰器修正2

import time

def index():
    print('welcome to index page')
    time.sleep(3)
    return 123

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

#==============================================================
def outter(func):
    # func=最原始那个home的内地址
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print('run time is %s' %(stop-start))
        return res
    return wrapper

index=outter(index) #index=outter(最原始那个index的内地址) #index=wrapper函数的内地址
home=outter(home) #index=outter(最原始那个home的内地址) #home=wrapper函数的内地址
#==============================================================

home('egon') #wrapper('egon')
index() #wrapper()

 

四、装饰器语法糖

'''

# @装饰器的名字:要在被装饰对象正上方单独一行写上
import time
def timmer(func): # func=最原始那个home的内地址
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print('run time is %s' %(stop-start))
        return res
    wrapper.__doc__=func.__doc__ # 装饰对象的注释
    wrapper.__name__=func.__name__ # 装饰对象的函数名称
    return wrapper

@timmer #index=timmer(index) ##index=timmer(最原始那个index的内地址) #index=wrapper函数的内地址
def index():
    """这是index功能"""
    print('welcome to index page')
    time.sleep(3)
    return 123

@timmer #home=timmer(home) #index=timmer(最原始那个home的内地址) #home=wrapper函数的内地址
def home(name):
    """这是home功能"""
    print('welcome %s to home page' %name)
    time.sleep(1)

# home('egon') #wrapper('egon')
# index() #wrapper()

# print(help(index))
# print(help(home))
# print(index.__doc__)

print(index.__name__)
'''

from functools import wraps

import time
def timmer(func): # func=最原始那个home的内地址
    @wraps(func)
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print('run time is %s' %(stop-start))
        return res
    return wrapper

@timmer
def index():
    """这是index功能"""
    print('welcome to index page')
    time.sleep(3)
    return 123

@timmer
def home(name):
    """这是home功能"""
    print('welcome %s to home page' %name)
    time.sleep(1)

print(help(index))
print(index.__name__) # 如果装饰器中的wrapper不写wrapper.__name__ = func.__name__ ,则返回warpper,否则返回被装饰对象的函数名称

 

五、有参装饰器

# 无参装饰器的模板
# def outter(func):
#     def wrapper(*args,**kwargs):
#         res=func(*args,**kwargs)
#         return res
#     return wrapper

import time

user_info={'current_user':None}

def auth(func):
    def wrapper(*args,**kwargs):
        if user_info['current_user'] is not None:
            res=func(*args,**kwargs)
            return res
        inp_user=input('username>>>: ').strip()
        inp_pwd=input('password>>>: ').strip()
        if inp_user == 'egon' and inp_pwd == '123':
            # 记录登录状态
            user_info['current_user']=inp_user

            print('login successful')
            res=func(*args,**kwargs)
            return res
        else:
            print('user or password error')
    return wrapper

@auth
def index():
    """这是index功能"""
    print('welcome to index page')
    time.sleep(2)
    return 123

@auth
def home(name):
    """这是home功能"""
    print('welcome %s to home page' %name)
    time.sleep(1)

# index()
# home('egon')


# 有参装饰器
def outter2(xxx,yyy):
    def outter(func):
        def wrapper(*args,**kwargs):
            res=func(*args,**kwargs)
            print(xxx)
            print(yyy)
            return res
        return wrapper
    return outter

import time

user_info={'current_user':None}

def auth2(engine='file'):
    def auth(func):
        def wrapper(*args,**kwargs):
            if user_info['current_user'] is not None:
                res=func(*args,**kwargs)
                return res
            inp_user=input('username>>>: ').strip()
            inp_pwd=input('password>>>: ').strip()

            if engine == 'file':
                print('基于文件的认证')
                if inp_user == 'egon' and inp_pwd == '123':
                    # 记录登录状态
                    user_info['current_user']=inp_user

                    print('login successful')
                    res=func(*args,**kwargs)
                    return res
                else:
                    print('user or password error')
            elif engine == 'mysql':
                print('基于mysql数据的认证')
            elif engine == 'ldap':
                print('基于ldap的认证')
            else:
                print('无法识别认证源')
        return wrapper
    return auth

@auth2(engine='mysql') # @auth ===> index=auth(最原始那个index的内存地址)===》index=wrapper
def index():
    """这是index功能"""
    print('welcome to index page')
    time.sleep(2)
    return 123

@auth2(engine='file')
def home(name):
    """这是home功能"""
    print('welcome %s to home page' %name)
    time.sleep(1)

index() #wrapper()
home('egon')

 

六、global与nonloal

# x=1
# def func():
#    x=2
#
# func()
# print(x)


# x=[]
# def func():
#    x.append(1)
#    x.append(2)
#    x.append(3)
#
# func()
# print(x)

# global: 在局部声明变量是全局变量
# x=1
# def func():
#     global x
#     x=2
#
# func()
# print(x)

# nonlocal:在局部声明变量是外层函数的变量

x=333
def f1():
    x=222
    def f2():
        x=111
        def f3():
            nonlocal x
            x=0
        f3()
        print('f2内部的x: ',x)
    f2()
    print('这是f1内部的x: ',x)

f1()
print(x)

 

posted @ 2018-09-27 19:46  仗剑煮大虾  阅读(249)  评论(0编辑  收藏  举报