Python之路Day12

今日大纲
1.函数的有用信息
2.带参数的装饰器
3.多个装饰器装饰一个函数


1.函数的有用信息
在函数体中用"""解释内容"""
print(login.__name__) 打印函数名称
print(login.__doc__) 打印函数体的解释内容
例1:
def login(username, password):
    """
    此函数是一个登陆函数
    :param username: 输入用户名
    :param password: 输入密码
    :return: 登录成功返回"登录成功!",否则返回"登录失败!"
    """
    if username == "david" and password == "123456":
        return "登录成功!"
    else:return "登录失败!"

print(login.__name__)
print(login.__doc__)
username1 = input("请输入账号:").strip()
password1 = input("请输入密码:").strip()
print(login(username1, password1))
例2:当遇到装饰器时,要打印被装饰函数的原函数名和原注释内容时
import time
from functools import wraps
def wrapper(f):
    @wraps(f)
    def inner(*args,**kwargs):
        """被装饰前的操作"""
        start_time = time.time()
        time.sleep(0.3)
        ret = f(*args,**kwargs)
        end_time = time.time()
        """被装饰后的操作"""
        print("函数执行时间是{}s".format(end_time-start_time))
        return ret
    return inner

@wrapper
def func1(a,b):
    """
    此函数的功能是打印传入的参数
    :param a: 任意数据类型
    :param b: 任意数据类型
    :return: "666......"
    """
    print(a, b)
    return "666......"

print(func1.__name__) # 打印被装饰的函数的函数名
print(func1.__doc__)  #  打印被装饰的函数的注释内容
print(func1(11, 22))

2.带参数的装饰器
情景:要为多个函数装上装饰器,因用户需要,需要实现可自主改变是否需要装饰的功能
import time
flag = True
def wrapper_out(flag):
    def wrapper(f):
        def inner(*args,**kwargs):
            """被装饰前的操作"""
            if flag:
                start_time = time.time()
                time.sleep(0.3)
                ret = f(*args,**kwargs)
                end_time = time.time()
                """被装饰后的操作"""
                print("函数执行时间是{}s".format(end_time-start_time))
                return ret
            else:
                ret = f(*args, **kwargs)
                return ret
        return inner
    return wrapper

flag1 = True   #只需要改变此处的flag的值即可对所有被装饰的函数选择是否需要被装饰,也可单独对某个函数传入特点的flag

@wrapper_out(flag1) #1,先执行wrapper_out(flag1)得到返回值wrapper;2,@wrapper  等价于 func1 = wrapper(func1)
def func1(*args,**kwargs):
    print()
    print(args)
    print(kwargs)
    return "666......"

@wrapper_out(flag1)
def func2(*args,**kwargs):
    print()
    print(args)
    print(kwargs)
    return "777....."

@wrapper_out(flag1)
def func3(*args,**kwargs):
    print()
    print(args)
    print(kwargs)
    return "888......"


print(func1(11, 22))
print(func2(333,444,555,name = "david",age = 18))
print(func3(*[111,222,333],*[444,555,666]))
补充1:局部只能引用全局的变量,不能修改,修改则需要global
count = 1
def func4():
    count = count + 1
    print(count)

func4() #报错,原因:count = count + 1 此处,count无法理解是引入的全局变量,还是重新形成的新变量
补充2:子函数只能引用父函数的变量,不能修改,如果要修改,nonlocal。
def func4():
    count = 3
    def inner():
        count = count + 1
        print(count)
func4() #报错

3.多个装饰器装饰一个函数
def wrapper1(f):    #2,f = func 
    def inner1(*args,**kwargs):
        print("111......")      #12,111......
        ret = f(*args,**kwargs)     #13,等价于 func($-_-$","$-_-$") #16 ret = "NB!"
        print("......111")      #17......111
        return ret      #18 
    return inner1       #3,返回inner1

def wrapper2(f):    #6,f = inner1 
    def inner2(*args,**kwargs):     #9 *args聚合 args = ("$-_-$","$-_-$")
        print("222......")      #10, 222......
        ret = f(*args,**kwargs)     #11.f("$-_-$","$-_-$") 等价于 inner1("$-_-$","$-_-$") #19 ret = "NB!"
        print("......222")      #20 .......222
        return ret      #21 ret = "NB!"
    return inner2       #7,返回inner2

@wrapper2    #5,func = wrapper2(func) 等于 func = wrapper2(inner1)  等于 func = inner2
@wrapper1    #1,首先执行靠近被装饰函数的装饰器 func = wrapper1(func) #4,func = inner1
def func(a, b):   #a = "$-_-$" b = "$-_-$"
    print("{}...666...{}".format(a, b))   #14,打印该语句
    return "NB!"  #15

print(func("$-_-$","$-_-$"))  #8,等价于inner2("$-_-$","$-_-$") #22 打印 NB!
执行结果:
222......
111......
$-_-$...666...$-_-$
......111
......222
NB!

执行结果的规律:类似于大箱子里套个小箱子,有几层套几层,最里面是被装饰的函数。

posted on 2018-05-15 16:53  Y易然R  阅读(109)  评论(0)    收藏  举报

导航