美文网首页
(十一)函数<2>

(十一)函数<2>

作者: 费云帆 | 来源:发表于2019-01-03 14:01 被阅读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
    
    • 内嵌函数可以直接引用外部函数的指针,但是该指针不能直接赋值(赋值先声明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()... # 第二次结果
    

    相关文章

      网友评论

          本文标题:(十一)函数<2>

          本文链接:https://www.haomeiwen.com/subject/doufrqtx.html