后台-插件-广告管理-内容页广告位一(手机)

# python基础（补充）：python三大器之装饰器

2021-04-18 18:38:50其他编程人已围观

def calc_sum(*args

# 函数作为返回值

``````def calc_sum(*args):
i = 0
for n in args:
i = i + n
return i
``````

``````def lazy_sum(*args):
def sum():
i = 0
for n in args:
i = i + n
return i

return sum
``````

``````f = lazy_sum(1, 3, 5, 7, 9)
print(f)

# <function lazy_sum.<locals>.sum at 0x000002C5C32328C8>
``````

``````print(f())

# 25
``````

``````f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
print(f1 == f2)
# False
``````

`f1()``f2()`的调用结果是互不影响的。

# 闭包

``````def count():
fs = []
for i in range(1, 4):
def f():
return i*i
fs.append(f)
return fs

f1, f2, f3 = count()
``````

``````print(f1())
# 9
print(f2())
# 9
print(f3())
# 9
``````

``````def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行，因此i的当前值被传入f()
return fs

f1, f2, f3 = count()
``````

``````print(f1())
# 1
print(f2())
# 4
print(f3())
# 9
``````

``````def now():
print('2021-04-17')

f = now
f()
``````

# `__name__`属性

``````print(now.__name__)  # now
print(f.__name__)  # now
``````

# 装饰器

decorator的本质就是闭包。所以，我们要定义一个能打印日志的decorator，可以定义如下：

``````def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)

return wrapper
``````

``````@log
def now():
print('2021-04-17')
``````

``````now()

# call now():
# 2021-04-17
``````

`@log`放到`now()`函数的定义处，相当于执行了语句：

``````now = log(now)
``````

`wrapper()`函数的参数定义是`(*args, **kw)`，因此，`wrapper()`函数可以接受任意参数的调用。在`wrapper()`函数内，首先打印日志，再紧接着调用原始函数。

``````def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
``````

``````@log('execute')
def now():
print('2021-04-17')
``````

``````now()

# execute now():
# 2021-04-17
``````

``````now = log('execute')(now)
``````

``````print(now.__name__)
# wrapper
``````

``````import functools

def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)

return wrapper
``````

``````import functools

def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)

return wrapper

return decorator

``````

`import functools`是导入`functools`模块。模块的概念稍候讲解。现在，只需记住在定义`wrapper()`的前面加上`@functools.wraps(func)`即可。

Tags：大器   补充   装饰   基础   python

 后台-插件-广告管理-内容页广告位二(手机)
 后台-插件-广告管理-内容页广告位三(手机)
 后台-插件-广告管理-内容页广告位四(手机)

## 文章评论

 留言与评论（共有 0 条评论）

 验证码：

## 站点信息

• 文章统计13614篇文章
• 浏览统计468次浏览
• 评论统计1个评论
• 标签管理标签云
• 统计数据：统计代码
• 微信公众号：扫描二维码，关注我们