美文网首页
(十一)函数<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>

    1.函数的参数是"函数": 进阶实例: 2.内嵌函数: 另一个实例 内嵌函数可以直接引用外部函数的指针,但是该指针...

  • 重构读书笔记-11_2-Pull_Up_Method

    重构第十一章 2.Pull Up Method(函数上移) 有些函数,在各个subclass中产生完全相同的结果,...

  • 十一.函数

    return的作用是:返回到调用函数的下一句函数,然后执行;assembly 汇编 disassembly 反...

  • python的学习笔记9

    十一、数组的创建 1、通过列表创建数组 2、numpy中定义的原生数组创建函数 (1)numpy.zeros(sh...

  • (十一)函数<1>

    1.概念理解:function:input(x)--->function--->output(x) 基本实例 延伸...

  • Day9总结

    1.回顾昨天学习知识: 1)字典2)集合 2.函数 1)函数语法 def 函数名():函数体 2)函数的调用 函数...

  • (十一)函数<4>几个特殊函数

    1.lambda()---匿名函数,可以把函数压缩在一行里搞定: 平常的作法: 使用lambda(): 或者这样:...

  • 廖雪峰 | 3.0 函数

    1 调用函数 2 定义函数 3 函数的参数 4 递归函数 1 调用函数 1,使用函数时,需要知道函数的名称和参数2...

  • 2019-01-05 day10function2 函数作为函数

    05 函数的参数是函数 3. 变量作为函数的实参 函数1作为函数2的实参 -- 函数2就是一个高阶函数 非常重要...

  • 函数2

    1.函数的返回值 在python中,每个函数都有返回值。当函数体中存在return语句的时候,返回值为return...

网友评论

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

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