在说python装饰器之前,先了解一下函数的重要特性。
定义一个add函数,函数的功能是实现两个数想加
# -*- coding: UTF-8 -*- def add(num1, num2): return num1 + num2 print(add) # 结果:<function add at 0x00000000021B3798>
可以看到,系统为函数分配了一个内存地址:0x00000000021B3798
# -*- coding: UTF-8 -*- def add(num1, num2): return num1 + num2 print(add) # 将函数这个对象赋值给 f f = add # 调用这个函数,传入两个实参,并且打印出来 print(f(1, 2)) # 结果等于 3
# -*- coding: UTF-8 -*- def add(num1, num2): return num1 + num2 print(add) def do_sth(): return add print(do_sth()(2, 3)) # 结果:5
# -*- coding: UTF-8 -*- def outer(): def inner(): print("This is inner..") return inner outer()() # This is inner..
先来了解一下map函数
map函数是根据指定函数对指定序列做映射,可以有效提高程序运行效率。
看一下map函数的源码:
map(func, *iterables)
map函数接受两个参数:
func:指定函数函数 iterables:可迭代对象,一个序列或者多个序列,即函数对应的实参
通过调用map,就可以将指定函数应用到可迭代对象中的每一个元素中。
然后生成一个新的可迭代对象。
例子:
def eval_square(x): return x * x result = map(eval_square, [1, 2, 3]) print(list(result)) # [1, 4, 9]
执行以下代码,很简单,打印“老大徒伤悲”
def test(): print("老大徒伤悲") test() # 老大徒伤悲
想要实现一个功能,在不改变 test 函数内部结构的前提下,在前面加一句 “少壮不努力”
结果是:
少壮不努力
老大徒伤悲
但这样的代码是有缺陷:test 函数直接返回了函数名,这样后面就不好调用了。
改进:
def name(func): def wrapper(): print("函数%s被调用了" % func.__name__) print("少壮不努力") return func() return wrapper @name def test(): print("老大徒伤悲") test() # test(): 调用test函数,相当于调用装饰器内函数 wrapper() # 所以执行的序列就明了了。 print(test.__name__) # 验证调用函数 test 的时候,其实是调用 装饰器的内函数 wrapper,即test() = wrapper()
输出结果:
函数test被调用了 少壮不努力 老大徒伤悲 wrapper
一个函数接收另一个函数作为参数,这种函数称之为高阶函数。