说说 Python 函数对象的本质

Python 函数对象本质上是 function 类的实例1

1 从示例说起

def factorial(n):
    '''return n!'''
    return 1 if n < 2 else n * factorial(n - 1)


r = factorial(42)
logging.info('r -> %s', r)
logging.info('__doc__ -> %s', factorial.__doc__)
logging.info('type(factorial)  -> %s', type(factorial))

运行结果:

INFO - r -> 1405006117752879898543142606244511569936384000000000
INFO - __doc__ -> return n!
INFO - type(factorial) -> <class 'function'>

这个示例首先定义了一个计算斐波那契数列的函数,可以看到 type(factorial) 的返回值是 <class 'function'>。也就验证了函数对象是 function 类的实例。

示例中还使用函数的 __doc__ 属性输出了函数定义中的注释。这一点比 Java 强大,Java 必须把注释定义在注解中才能通过代码获取到。

2 help 函数

python 中还有一个 help 函数,它可以接受一个自定义函数作为入参,然后输出该函数的说明文档。形如:

help(factorial)

运行结果:

Help on function factorial in module __main__:

factorial(n)
    return n!

3 函数别名与函数传参

函数可以赋值给变量,也可以作为其他函数的入参。

f = factorial
logging.info('f -> %s', f)
logging.info('f(5) -> %s', f(5))

r = map(factorial, range(11))
logging.info('r -> %s', r)

r = list(map(f, range(11)))
logging.info('r -> %s', r)

运行结果:

INFO - f -> <function factorial at 0x0000027278917798>
INFO - f(5) -> 120
INFO - r -> <map object at 0x000002727893F588>
INFO - r -> [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

示例中首先把之前定义的斐波那契数列函数赋值给变量 f;可以看到这个变量本身就是 factorial 函数的引用。还可以像使用 factorial 函数一样,直接给 f 函数传参,计算出想要的斐波那契数列结果。

接着把 factorial 函数传入 Python 的 map() 函数。map() 函数的语法为:map(function, iterable, ...),它会以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表2

因为在 Pyhon 3.x 中 map() 函数只返回迭代器,所以示例中对其进行 list 转换。这样就输出了从 0 到 11 作为入参的各自斐波那契结果列表。因为 range() 函数的语法为:range(start, stop[, step]),默认从 0 开始3,所以范围是从 0 到 11。


函数与整数、字符串与字典一样,它们都是 Python 世界中的一等公民。


参考资料:
【1】Luciano Ramalho (作者),安道,吴珂 (译者).流畅的Python[M].人民邮电出版社,2017:239-240.
【2】Python map() 函数.
【3】Python range() 函数用法.

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页