(十一)函数<2>

2019-01-03  本文已影响0人  费云帆

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
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
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()...

结论就是,当"函数"作为"对象"传入其他"函数"的时候,这时候可以考虑用"装饰器"的写法,使代码更为简洁

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()... # 第二次结果
上一篇 下一篇

猜你喜欢

热点阅读