13、Python之函数对象与闭包

Python函数 / 2020-11-20

1、函数对象是什么?

说到函数对象,就得先提到Python人称面向对象编程,即用类(class)和对象(object)进行面向对象编程!类我还没开始学,不过不影响理解概念!下面是对它的一个简单理解,可能不是十分精确!

我们总是习惯性给地球上的东西按照各种属性来分门别类!举个例子,地球上的人类作为一个类别(class),我们共同属性之一是直立行走,这一下子就和地球上绝大多数物种区分开来了!人类是一个大类,我是一个人,归属于人类这个类别!那么我这个“东西”,就是人类的一个对象(object)!

2、为何要有它?

Linux上一切皆文件,Python里一切皆对象!函数也是对象、有其属性!可以赋值给其它函数、可以被当成参数传递、也可以被当做其它函数的返回值!因为啊,归根到底就是引用名称所对应的内存地址而已!通过种种操作,构建复杂程序!

3、如何使用它?

按照上面的几个作用,来演示一下!

3.1、为其它函数赋值

上一节作用域的nonlocal其实也提过了,这里再演示一下!函数print_str给函数str2变量赋值,当然了要牢记上节提到的名称空间与作用域概念!

>>> def print_str():
...     sanxi=666
...     def str2():
...             print(sanxi)
...     str2()
... 
>>> print_str()
666
3.2、作为参数被传递

如下所示,因为函数传递的是内存地址,而函数特点是不调用不执行代码,因此print_str调用结果仅仅是打印hello的内存地址而不是调用hello的代码打印"hello,world"!

# 先定义一个函数
>>> def hello():
...     print('hello,world')
... 
# 再定义个函数
>>> def print_str(arg):
...     print(arg)
... 
# 把hello当做是print_str的一个参数来调用
>>> print_str(hello)
<function hello at 0x7f15345ae158>
3.3、作为返回值

函数作为一个对象,可以作为某个函数的返回值!如果想拿到hello调用结果,需要return将其内存地址作为返回值!这里return后,hello不能加括号,加了括号就是调用函数了!

def print_str():
    def hello(num):
        print(7**2 + num)
    return hello

number = print_str()
number(66)

# 执行得到结果
115

4、闭包函数

4.1、什么是闭包函数?

把上面的例子稍微改改,hello有使用a这个变量,按照此前说的名称空间来查找,hello中并没有定义a,所以往外查询,发现外层函数print_str有定义,因此直接拿来用,这时a就可以称为hello的环境变量!

所以说一个嵌套函数和它的环境变量被合称为闭包函数

def print_str():
    a = 3
    def hello(num):
        print(7**a + num)
    return hello

number = print_str()
number(66)
4.2、为何要用它?

跟函数一个道理,提高代码可重复使用的作用,更大的作用在后面装饰器中会较为详细地阐述!

4.3、如何使用它?

上面就是例子

世间微尘里 独爱茶酒中