标签:容器 返回值 __name__ and tools 通过 装饰类 pre people
前言:函数名是一个特性的变量,可以作为容器的元素,也可以作为函数的参数,也可以当做返回值。
闭包定义:
内层函数对外层函数(非全局)变量的引用,这个内层函数就可以成为闭包
在Python中我们用__closure__
来检查函数是否是闭包
def func1():
name = '张三'
def func2():
print(name) # 能够访问到外层作用域的变量
func2()
print(func2.__closure__) # (<cell at 0x1036c7438: str object at 0x10389d088>,)
func1()
print(func1.__closure__) # None
前言:软件设计原则:开闭原则,又称开放封闭原则
def create_people():
print(‘女娲真厉害,捏个泥吹口气就成了人!‘)
def a(func):
def b():
print(‘洒点水‘)
func()
return b
ret = a(create_people)
ret()
通过装饰器语法等同于
def a(func):
def b():
print(‘洒点水‘)
func()
return b
@a # 装饰器语法糖的作用就是上述函数ret()
def create_people():
print(‘女娲真厉害,捏个泥吹口气就成了人!‘)
create_people()
装饰带返回值的函数,即return出被装饰函数的执行结果
def foo(func): # 接收的参数是一个函数名
def bar(): # 定义一个内层函数
print("这里是新功能...") # 新功能
r = func() # 在内存函数中拿到被装饰函数的结果
return r # 返回被装饰函数的执行结果
return bar
# 定义一个有返回值的函数
@foo
def f1():
return ‘嘿嘿嘿‘
# 调用被装饰函数
ret = f1() # 调用被装饰函数并拿到结果
print(ret)
装饰带参数的函数
def func1(func): # 接收的参数为一个函数名
def inner(*args, **kwargs): # 这里需要定义和被装饰函数相同的参数
print("新功能") # 新功能
ret = func(*args, **kwargs) #被装饰的函数和参数
print("新功能")
return ret
return inner
# 定义一个需要俩个参数的函数
@func1
def func(a, b):
return a + b
ret = func(3, 5)
print(ret)
带参数的装饰器 即在装饰器外在写一层函数,从而使其带参数
def d(a=None): # 定义一个外层函数,给装饰器传参数
def func1(func): # 接收的是一个函数名
def inner(*args, **kwargs): # 被装饰的函数,和参数
if a:
print(f"欢迎来到{a}") #添加新功能
else:
print("欢迎来到王者荣耀")
func(*args, **kwargs)
return inner
return func1
# @d("英雄联盟")
# def func(st):
# print(st)
# func("敌军还有三十秒到达战场")
# 欢迎来到英雄联盟
# 敌军还有三十秒到达战场
@d()
def func(st):
print(st)
func("敌军还有三十秒到达战场")
# 欢迎来到王者荣耀
# 敌军还有三十秒到达战场
装饰器修复技术
定义:被装饰的函数最终都会失去本来的__doc__等信息, Python给我们提供了一个修复被装饰函数的工具。
from functools import wraps #导入
print(f1.__doc__)
print(f1.__name__)
多个装饰器装饰同一函数
def foo1(func):
print("d1")
def inner1():
print("inner1")
return "<i>{}</i>".format(func())
return inner1
def foo2(func):
print("d2")
def inner2():
print("inner2")
return "<b>{}</b>".format(func())
return inner2
@foo1
@foo2
def f1():
return "Hello Andy"
# f1 = foo2(f1) ==> print("d2") ==> f1 = inner2
# f1 = foo1(f1) ==> print("d1") ==> f1 = foo1(inner2) ==> inner1
ret = f1() # 调用f1() ==> inner1() ==> <i>inner2()</i> ==> <i><b>inner1()</b></i> ==> <i><b>Hello Andy</b></i>
print(ret)
类装饰器
class D(object):
def __init__(self, a=None):
self.a = a
self.mode = "装饰"
def __call__(self, *args, **kwargs):
if self.mode == "装饰":
self.func = args[0] # 默认第一个参数是被装饰的函数
self.mode = "调用"
return self
# 当self.mode == "调用"时,执行下面的代码(也就是调用使用类装饰的函数时执行)
if self.a:
print("欢迎来到{}页面。".format(self.a))
else:
print("欢迎来到首页。")
self.func(*args, **kwargs)
@D()
def index(name):
print("Hello {}.".format(name))
@D("电影")
def movie(name):
print("Hello {}.".format(name))
if __name__ == ‘__main__‘:
index(‘张三‘)
movie(‘张三‘)
装饰类
# 定义一个类装饰器
class D(object):
def __call__(self, cls):
class Inner(cls):
# 重写被装饰类的f方法
def f(self):
print(‘Hello 张三.‘)
return Inner
@D()
class C(object): # 被装饰的类
# 有一个实例方法
def f(self):
print("Hello world.")
if __name__ == ‘__main__‘:
c = C()
c.f()
标签:容器 返回值 __name__ and tools 通过 装饰类 pre people
原文地址:https://www.cnblogs.com/yuncong/p/9886555.html