Python的函数是第一类对象(first-class object)。你可以把一个函数复制给变量,或者把函数存储在一个结构中。可以像参数一样把函数传递进另一个函数,还可以从一个函数中返回另一个函数。
知道了这些,有助于理解 lambda 和装饰器。这也是 面向函数编程 的一部分。
通过这篇文章,我用最简单的例子,为大家做个说明。
首先定义一个函数,然后调用它:
输出:hello alex!
函数是对象
和列表,字符串一样,函数是对象。我们可以把函数赋值给一个变量。
输出:hello john!
hi = hello 这一行并没有调用函数 hello 。实际上是 hi 引用了函数 hello。现在 hi 是可调用的,最后执行 hi('john'),调用函数代码。打印了 hello john!。
函数对象和函数的名称是两个概念,在上面的例子,hi 和 hello 都指向同一个函数对象。如果删除 hello 并不影响 hi,它继续指向原来的函数对象。
输出:hello everyone!
另外,函数在创建阶段就赋予了名称。上面的函数对象创建的时候,指定了名称 hello ,我们把 hi 指向了函数对象,并不影响它之前的名称。print(hi.__name__) # 输出 hello
可见,输出值还是 hello。
函数可以存储在数据结构中
因为函数是第一类对象,你可以把它存入数据结构中,比如列表:
输出:
可以不用赋值给变量,直接通过列表索引调用函数对象:print(funcs[0]('maggie')) # 输出 hello maggie!
函数可以传递给其他的函数
函数可以通过参数传递进其他函数。
输出:hello alex!
这里,把 hello 函数传递进了 hello_alex。在 hello_alex 调用了函数 hello,并打印。
另一个例子:
输出:HELLO ALEX!
我们写了新的函数 hello_alex_upper,这个函数将默认的输出大写。
函数作为参数传递进另一个函数,这个特性是非常强大的。你可以不修改之前的代码,直接为你的应用增加其他的行为。
函数能够接收另一个函数作为参数,这种函数被称为 高阶函数(high order function)。属于面向函数编程的范畴。
在 Python 中使用高阶函数的一个经典的例子是 map 函数。它接收一个函数和一个序列。序列的每一个元素都经过函数的处理,然后返回修改过的结果序列。>>> list(map(str.upper, ['hello', 'world']))['HELLO', 'WORLD']
函数可以嵌套
Python 允许一个函数定义在另一个函数里,这通常被称为 嵌套函数 (nested function) 或者 内部函数(inner function)。
输出:GREET ALEX
注意,内部函数 upper 在外部是访问不了的,如果你试图访问,会报 AttributeError 错误。print(greet.upper)
报错:Traceback (most recent call last): File "first-class-object.py", line 38, in
print(greet.upper)AttributeError: 'function' object has no attribute 'upper'
如果你想访问内部函数,需要返回该内部函数。
对象也可以像函数那样调用
我们从类实例化,得到一个对象,那么对象就可以调用类定义的相关方法。其实对象也可以像函数那样调用,只需要在类上定义一个函数 __call__。
输出:alexalex
在背后,能够像方法一样调用对象,实际上是对象调用它的 __call__ 方法。
留言与评论(共有 0 条评论) |