python闭包满足的三个条件_python闭包及装饰器

一、闭包

闭包的概念:一个完整的闭包必须满足三个条件:

(1)函数中嵌套一个函数

(2)外层函数返回内层函数的变量名

(3)内层函数对外部作用域有一个非全局的变量进行引用

最简单的闭包案例:

defouter():

x=100

definner():

y=x*2

print(y)returninnerprint(outer()) #运行结果:.inner at 0x110d3ab70>

outer()() #运行结果:打印200

二、装饰器

python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象。

1、装饰器结构

def w1(func):

def inner():

# 验证1

# 验证2

# 验证3

return func()

return inner

@w1

def f1():

print 'f1'

2、函数装饰器

1)函数不带参数

#函数装饰器-函数不带参数

import time

def runtime(func):

def wrapper():

start = time.time()

f = func() # 原函数

end = time.time()

print("运行时长:%.4f 秒" % (end-start))

return f

return wrapper

@runtime

def func_a():

print("func_a")

time.sleep(0.5)

@runtime

def func_b():

print("func_b")

time.sleep(0.8)

if __name__ == '__main__':

func_a()

func_b()

1339103-20200430160336683-45948635.png

2)函数带参数

#函数装饰器-函数带参数

import time

def runtime(func):

def wrapper(*args,**kwargs):

start = time.time()

f = func(*args,**kwargs) # 原函数

end = time.time()

print("运行时长:%.4f 秒" % (end-start))

return f

return wrapper

@runtime

def func_a(a):

print("func_a")

print("a="+a)

time.sleep(0.5)

@runtime

def func_b(b,c="3"):

print("func_b")

print("b="+b)

print("c="+c)

time.sleep(0.8)

if __name__ == '__main__':

func_a("1")

func_b("2")

1339103-20200430160915590-262186850.png

3)装饰器带参数

#函数装饰器-装饰器带参数

import time

def runtime(slowly=1):

def wrapper(func):

def inner_wrapper(*args, **kwargs):

start = time.time()

f = func(*args, **kwargs) # 原函数

end = time.time()

t = end-start

print("运行时长:%.4f秒"%t)

time.sleep(slowly) # 延迟效果

new_end = time.time()

print("延时时长:%.4f 秒" % (new_end-start))

return f

return inner_wrapper

return wrapper

@runtime(1.5)

def func_a(a):

print("a="+a)

time.sleep(0.5)

@runtime(0.5)

def func_b(b, c="c"):

print("b="+b)

print("c="+c)

time.sleep(0.8)

if __name__ == '__main__':

func_a("a")

func_b("b", c="c")

1339103-20200430161554648-1412959660.png

3、类装饰器

1)装饰器不带参数

#类装饰器-装饰器带参数

import time

class runtime:

def __call__(self, func):

def inner_wrapper(*args, **kwargs):

start = time.time()

f = func(*args, **kwargs) # 原函数

end = time.time()

t = end-start

print("运行时长:%.4f秒"%t)

return f

return inner_wrapper

@runtime()

def func_a(a):

print("a="+a)

time.sleep(0.5)

@runtime()

def func_b(b, c="c"):

print("b="+b)

print("c="+c)

time.sleep(0.8)

if __name__ == '__main__':

func_a("a")

func_b("b", c="c")

1339103-20200430162617995-2023835125.png

2)装饰器带参数

#类装饰器-装饰器带参数

import time

class runtime:

def __init__(self,slowly=1):

self.slowly=slowly

def __call__(self, func):

def inner_wrapper(*args, **kwargs):

start = time.time()

f = func(*args, **kwargs) # 原函数

end = time.time()

t = end-start

print("运行时长:%.4f秒"%t)

time.sleep(self.slowly) # 延迟效果

new_end = time.time()

print("延时时长:%.4f 秒" % (new_end-start))

return f

return inner_wrapper

@runtime(1.5)

def func_a(a):

print("a="+a)

time.sleep(0.5)

@runtime(0.5)

def func_b(b, c="c"):

print("b="+b)

print("c="+c)

time.sleep(0.8)

if __name__ == '__main__':

func_a("a")

func_b("b", c="c")

1339103-20200430162455384-1419148654.png

4、内置装饰器

classMyTest(object):def __init__(self,name):

self.name=name

@classmethoddef class_method(cls): #被classmethod装饰了之后,该方法就是一个类方法

print('这是类方法') #cls代表的是类本身

print(cls)

@staticmethoddefstatic():print("这是静态方法")

@propertydef read_property(self): #设定只读属性

print("装饰器装饰完后,该方法变成只读属性")return "18"

def sub(self): #普通实例方法

print("sub中的self",self)

m=MyTest("test")

m.class_method()

MyTest.class_method()print("-----------------")

m.static()

MyTest.static()print("-------------------")print("打印只读属性:"+m.read_property)print("----------------")

m.sub()

运行结果:

这是类方法这是类方法

-----------------这是静态方法

这是静态方法-------------------装饰器装饰完后,该方法变成只读属性

打印只读属性:18

----------------sub中的self<__main__.MyTest object at 0x109c899e8>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值