1.函数的参数是"函数":
def bar():
print('I am in bar()')
# foo接收的参数,是一个函数对象
def foo(func):
func()
foo(bar)
>>>
I am in bar()
- 进阶实例:
def convert(func,seq):
return [func(i) for i in seq]
if __name__=='__main__':
#myseq=[11,22,33,44]#结果一样
myseq=(11,22,33,44)
print(convert(str,myseq))
>>>
['11', '22', '33', '44']
2.内嵌函数:
def foo():
# 不能单独调用bar(),它只在foo()内部生效
def bar():
print('bar() is running')
print('foo() is running')
foo()
>>>
# 显然,bar()没有被调用
foo() is running
# 修改一下
def foo():
def bar():
print('bar() is running')
print('foo() is running')
bar()
foo()
>>>
foo() is running
bar() is running
- 另一个实例
def foo():
a=1
def bar():
b=a+1
print('b={}'.format(b))
bar()
print('a={}'.format(a))
foo()
>>>
b=2
a=1
- 内嵌函数可以直接引用外部函数的指针,但是该指针不能直接赋值(赋值先声明nonlocal):
def foo():
a=1
def bar():
a=a+1 #修改之处
print('a={}'.format(a))
bar()
print('a={}'.format(a))
foo()
>>>
UnboundLocalError: local variable 'a' referenced before assignment
# 不能赋值情况
def foo():
a=3
def bar():
return a
return bar
f=foo()
print(f())
>>>
3
- 外部指针重新赋值---nonlocal
def foo():
a=1
def bar():
nonlocal a #修改之处
a=a+1
print('bar(a)={}'.format(a))
bar()
print('foo(a)={}'.format(a))
foo()
>>>
bar(a)=2
foo(a)=2
- 内嵌函数返回函数对象实例:
def maker(n):
def action(x):
return x**n
return action
test1=maker(2)
print(test1)
>>>
# maker(2)返回的是一个函数对象
<function maker.<locals>.action at 0x0000000000957F28>
# 相当于maker(2)(3)
# maker(2)返回action对象
# action(3),所以输出9
test2=test1(3)
print(test2)
>>>
9
- 抛砖引玉---装饰器
def bar():
print('I am in bar()')
def foo(fun):
def wrap():
print('start')
fun()
print('end')
print(fun.__name__)
return wrap
f=foo(bar)
print(f)
f()
>>>
<function foo.<locals>.wrap at 0x00000000033F9BF8>
start
I am in bar()
end
bar
@装饰器---上面的实例换一种写法:
def foo(fun):
def wrap():
print('start')
fun()
print('end')
print(fun.__name__)
return wrap
# 装饰器
# foo()装饰器函数用来装饰bar()
@foo
def bar():
print('I am in bar()')
# 有了装饰器,直接调用函数即可
bar()
# foo(bar)(),这么写感觉奇怪的话,就使用装饰器吧
>>>
start
I am in bar()
end
bar
装饰器使代码更加简洁,可读性更强,目前而言,用在内嵌函数比较多.
def foo(func):
print("I'm in foo()")
return func
@foo
def add_func(x,y):
return x+y
print(add_func(1,2))
>>>
I'm in foo()
3
我觉得装饰写法更为贴切吧....
我的理解,装饰器须传入函数对象,并且返回该函数对象,被装饰的函数就自己发挥了...
review版---关于装饰器
def test_func(func):
print("This is a test function!!!")
# 这里如果写成 func()就报错了,因为调用的时候变成了"bar()()"
# 报错信息:TypeError: 'NoneType' object is not callable
return func
# 装饰器相当于把装饰的函数作为对象传入该装饰器函数
@test_func
def bar():
print('I am in bar()...')
bar()
>>>
This is a test function!!!
I am in bar()...
上面例子再修改下,用内嵌函数也可以:
def test_func(func):
print("This is a test function!!!")
# 修改之处,添加一个内嵌函数来返回
def wrap():
func()
return wrap
@test_func
def bar():
print('I am in bar()...')
bar()
>>>
This is a test function!!!
I am in bar()...
结论就是,当"函数"作为"对象"传入其他"函数"的时候,这时候可以考虑用"装饰器"的写法,使代码更为简洁
- 再次review,使用装饰器的时候,被装饰的函数只能执行一次,执行第二次的时候,会执行本身...
def test_func(func):
print("I am in test_func()...")
return func
@test_func
def add():
print('I am in add()...')
add()
add()
>>>
I am in test_func()...
I am in add()... # 第一次结果
I am in add()... # 第二次结果
网友评论