Day-1-decorator

# review python by zzk
# From https://www.cnblogs.com/Eva-J/p/7277026.html
# and my point

# function 函数
#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world!!!!!!"
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen()
# print('str_len : %s'%str_len)  # str_len : 17

# 不写return的情况下,会默认返回一个None
# 一旦遇到return,结束整个函数

# 可以返回任意多个、任意数据类型的值
def ret_demo1():
    """
    :return: 返回多个值
    """
    return 1,2,3,4


def ret_demo2():
    """
    返回多个任意类型的值
    :return:
    """
    return 1,['a','b'],3,4


ret1 = ret_demo1()
# print(ret1)     # (1, 2, 3, 4)
ret2 = ret_demo2()
# print(ret2)     # (1, ['a', 'b'], 3, 4)
# 返回的多个值会被组织成元组被返回,也可以用多个值来接收
#返回多个值,用多个变量接收
a,b,c,d = ret_demo2()
# print(a,b,c,d)      # 1 ['a', 'b'] 3 4
# 但是不能这样,只用对应的值去接收
# a,b,c = ret_demo2()
# print(a,b,c)

# >>> 1,2  #python中把用逗号分割的多个值就认为是一个元组。
# (1, 2)
# >>> 1,2,3,4
# (1, 2, 3, 4)
# >>> (1,2,3,4)
# (1, 2, 3, 4)

# 函数的动态参数
def mysum(*args):
    the_sum = 0
    for i in args:
        the_sum+=i
    return the_sum

the_sum = mysum(1,2,3,4)
# print(the_sum)      # 10


def stu_info(**kwargs):
    # print(kwargs)       # 可以看到,**kwargs把对应的内容当做一个字典传入
    # print(kwargs['name'],kwargs['sex'])
    pass

stu_info(name = 'alex',sex = 'male')

# {'name': 'alex', 'sex': 'male'}
# alex male

# 装饰器
# 需求,给全部函数加一个计算执行时间的功能
# import time
# def timer(func):
#     """
#     执行传入的函数,并计算执行时间
#     :param func: 传入的函数
#     :return: None
#     """
#     start = time.time()
#     func()
#     print(time.time() - start)
#
# def func1():
#     print('in func1')
#
#
# def func2():
#     print('in func2')
#
# timer(func1)
# timer(func2)

# 装饰器的形成过程

# 第一版,上面一个是统一要调用一次func1,这次不改原来的代码,还是执行func()这个函数
# 因此,让 timer这个函数返回一个函数 inner,

# import time
#
# def func1():
#     print('in func1')
#
# def timer(func):
#     def inner():
#         start = time.time()
#         func()
#         print(time.time() - start)
#     return inner
#
# func1 = timer(func1)        # 这个时候,func1其实还没有执行
# 关于这点,其实很明显,timer函数里面只是对inner函数的定义,没有调用,所以不会执行,当inner返回之后,才调用执行
# print(func1)        # <function timer.<locals>.inner at 0x1044d9400>
# print(type(func1))      # <class 'function'>
# func1()       # 这个时候才执行


# 加上python的语法糖
import time
# def timer(func):
#     def inner():
#         start = time.time()
#         func()
#         print(time.time() - start)
#     return inner
#
# @timer   # ==> func1 = timer(func1)
# def func1():
#     print('in func1')
#
#
# func1()

# 简单的总结
# 装饰器的本质:一个闭包函数
# 装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

# def timer(func):
#     print('---timer---')
#     def inner(a):
#         print('---inner---')
#         start = time.time()
#         func(a)  # inner里面执行了传入的函数
#         print(time.time() - start)
#     return inner
#
# @timer      # ==> func1 = timer(func1)
# def func1(a):
#     print('---func1---')
#     # print(a)
#
# func1(1)
# # 从执行结果看,执行带装饰器的函数func1,会先执行装饰器timer,这就能看到装饰器函数的执行流程
#
# # ---timer---
# # ---inner---
# # ---func1---
# # 9.059906005859375e-06

# 装饰器——成功hold住所有函数传参
# import time
# def timer(func):
#     def inner(*args,**kwargs):
#         start = time.time()
#         re = func(*args,**kwargs)
#         print(time.time() - start)
#         # return re
#     return inner
#
# @timer   #==> func1 = timer(func1)
# def func1(a,b):
#     print('{},{}in func1'.format(a,b))
#
# @timer   #==> func2 = timer(func2)
# def func2(a):
#     print('in func2 and get a:%s'%(a))
#     return 'fun2 over'
#
# func1('aaaaaa','bbbbbb')
# print(func2('aaaaaa'))
#
# # aaaaaa,bbbbbbin func1
# # 4.100799560546875e-05
# # in func2 and get a:aaaaaa
# # 1.0013580322265625e-05
# # None


# # 装饰器——带返回值的装饰器
# import time
# def timer(func):
#     print('---timer---')
#     def inner(*args,**kwargs):
#         print('---inner---')        # 要记住这里先执行的是inner
#         print('*args is {},**kwargs is {}'.format(*args,**kwargs))
#         start = time.time()
#         re = func(*args,**kwargs)       # 下面的in func2这个输出是这里执行的
#         print(time.time() - start)
#         return re
#     return inner
#
# @timer   #==> func2 = timer(func2)  其实这里把func2传入timmer以后,返回inner作为func2,然后是会执行func2的!!!
# def func2(*args,**kwargs):
#     print('---in func2---')
#     return 'fun2 over'
#
# func2('aaaaaa',{'zzk':'aj'})
# # print(func2('aaaaaa'))


# def index():
#     '''这是一个主页信息'''
#     print('from index')
#
# print(index.__doc__)    #查看函数注释的方法
# print(index.__name__)   #查看函数名的方法


# 开放封闭原则
# 1.对扩展是开放的
#  为什么要对扩展开放呢?
#  我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。
#
# 2.对修改是封闭的
#  为什么要对修改封闭呢?
#  就像我们刚刚提到的,因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经
# 在使用该函数的用户。
# 装饰器完美的遵循了这个开放封闭原则。

# 装饰器的主要功能:
# 在不改变函数调用方式的基础上在函数的前、后添加功能
# def timer(func):
#     def inner(*args,**kwargs):
#         '''执行函数之前要做的'''
#         re = func(*args,**kwargs)
#         '''执行函数之后要做的'''
#         return re
#     return inner


# from functools import wraps
# def deco(func):
#     @wraps(func) #加在最内层函数正上方
#     def wrapper(*args,**kwargs):
#         return func(*args,**kwargs)
#     return wrapper


# 带参数的装饰器

# # 多个装饰器装饰同一个函数
# def wrapper1(func):
#     def inner1():
#         print('wrapper1 ,before func')
#         func()
#         print('wrapper1 ,after func')
#     return inner1
#
# def wrapper2(func):
#     def inner2():
#         print('wrapper2 ,before func')
#         func()
#         print('wrapper2 ,after func')
#     return inner2
#
# @wrapper2
# @wrapper1
# def f():
#     print('in f')
#
# f()
#
# # wrapper2 ,before func
# # wrapper1 ,before func
# # in f
# # wrapper1 ,after func
# # wrapper2 ,after func
#
# # 这里的执行顺序是,先检测到wrapper2这个装饰器,执行wrapper2,在这里定义了inner2,然后return inner2(),此后执行inner2
# # print('wrapper1 ,before func'),然后遇到了func()
# # 这个时候,要执行f()这个函数,又检测到f函数还有一个装饰器@wrapper1,执行wrapper1(func),
# # 在这里定义了inner1,然后return inner1(),此后执行inner1
# # print('wrapper1 ,before func')
# # 然后执行func(),就是f(),后面print('wrapper1 ,after func'),回到wrapper2,执行print('wrapper2 ,after func')


# 闭包的作用,详解 https://www.cnblogs.com/JohnABC/p/4076855.html








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值