python装饰器

闭包

# def outer():
#     a = 10
# print(f"a is {a}")
# outer()
# print(a)
def outer(x):
    a = 300
    def inner():
        print(x+a)
    return inner #inner()是返回函数值
d = outer(10)
d()
#引用的外部函数的变量都存在__closure__里面,是个元组类型
#闭包形成的条件:
# 1,必须要有一个内嵌函数
# 2,内函数必须引用外函数的变量
# 3,外函数必须返回内函数

# 变量解析原则LEGB:
# 先找local
# 再找上一层
# 再找global全局
# 再找builtin内建

# def outer():
#     tmp_list = []
#     def inner(name):
#         tmp_list.append(1)
#         print(f"{name} --{tmp_list}")
#     return inner
# d1 = outer()
# d2 =outer()
# d1("d1")
# d2("d2")
# print(id(outer()),id(outer()))#内存空间的地址一样:没将他们赋给一个变量,就是匿名变量,匿名变量都会放在同一个空间
#虽然代码一样,但是每次调用外函数,都会重新执行,创建一个新的tmp_list和inne

 

装饰器是一种设计模式,如果有一个类或者函数希望添加其他或函数的一些功能,
# 而不希望通过继承或者直接修改源代码实现
#
# 在不改变函数或者类的源代码的基础上,为函数或类添加额外功能
#装饰器的本质就是闭包函数,不同之处是外函数需要传入一个callable对象
# import time

# def func1():
#     time.sleep(2)
#     print("func1......")
#
#
# def func2():
#     time.sleep(3)
#     print("func2......")

# start = time.time()
# func1()
# end = time.time()
# result = end - start
# print(result)
#统计运行时间的装饰器
# import time
# import functools
# # 必须传入一个callable对象
# def runtime(func):
#     #保留传进来的函数的元数据,将他的元数据赋值给inner
#     @functools.wraps(func)
#     def inner(*args,**kwargs): #让装饰器更通用
#         start = time.time()
#         result=func(*args)
#         end = time.time()
#         print(f"函数执行花了{end-start}s")
#         return result
#     return inner
#
# @runtime #@修饰符去使用装饰器,func1=runtime(func1)
# def func1():
#     time.sleep(2)
#     print("func1...")
#
# @runtime
# def func2(a,b):
#     time.sleep(3)
#     print("func2...")
#     return a+b
#
# func1()
# func2(1,2)

#要求都写在内函数里面
def deco(username):
    def login_required(func):
        def inner(*args):
            if username == 'root':
                result = func(*args)
                return result
            else:
                print("no permission")
        return inner
    return login_required
#add=runtime(login_required(add))
@deco(username = input("input your name"))
def compute(a,b):
    return a+b
res=compute(1,2)
print(res)
#可以应用多个内函数,从最上面的装饰器的内函数开始执行,
# 一层一层的内函数往里面执行

 装饰器的应用

#自身传入不参数的装饰器,使用两层函数定义
#自身传入参数的装饰器,使用三层函数定义
# import functools
# import time
# def deco(name):
#     def runtime(func):
#         @functools.wraps(func)
#         def inner(*args, **kwargs):  # 让装饰器更通用
#             start = time.time()
#             result = func(*args)
#             end = time.time()
#             print(f"函数执行花了{end - start}s")
#             return result
#         return inner
#     return runtime
#
# #runtime = deco(name="sc")
# #func1 = runtime(func1)
# @deco(name="sc")
# def func1():
#     time.sleep(3)
#     print("this is func1")
# func1()

 ###基于类实现装饰器

# class A():
#     def __init__(self,func):
#         self.func = func
#     def __call__(self):#添加的东西放到call里面
#         print("this is call")
#         self.func()
# @A #本质func1=A(func1)
# def func1():
#     print("i am func1...")
# func1()

# import time
# class Time():
#     def __init__(self,func):
#         self.func = func
#     def __call__(self,*args,**kwargs):
#         start = time.time()
#         res = self.func(*args,**kwargs)
#         end = time.time()
#         print(f"函数执行花了{end-start}s")
#         return res
#
# @Time
# def func1():
#     time.sleep(2)
#     print("func1")
# func1()
# #func1就是call

 

####装饰器带参数
# #func1 = runtime(func1)
#先执行实例化得到一个对象
# ,通过对象的调用又得到一个callable对象

 

###装饰类
def outer(cls):
    def inner(*args,**kwargs):
        print(f"class name is:{cls.__name__}")
        return cls(*args,**kwargs)
    return inner
@outer#本质上就是A= outer(A)
class A():
    def __init__(self,name):
        self.name = name

print(type(A))
m = A("sc")
print(m.name)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值