[关闭]
@songying 2018-07-16T09:59:08.000000Z 字数 2336 阅读 1100

python 一等函数

python函数


来源: 流畅的python 第5章

一等函数定义

在Python中,所有函数都是一等函数。

将函数视作对象

python中,函数就是对象。
有了一等函数,就可以使用函数式风格编程。

高阶函数

定义: 接受函数为参数,或者把函数作为结果返回的函数是高阶函数

函数式编程中,map、filter 和 reduce是常见的高阶函数, 但如今 map、filter 和 reduce 这三个高阶函数还能见到,不过多数使用场景下都有更好的替代品。
在python3中, map, filter依旧是内置函数,但是reduce已经移到 functools模块了。

匿名函数

python中使用lambda来创建匿名函数。
lambda只是语法糖,与 def 语句一样,lambda 表达式会创建函数对象。

除了作为参数传给高阶函数之外,Python 很少使用匿名函数。


可调用对象

  • 用户定义的函数: 使用 def 语句或 lambda 表达式创建。
  • 内置函数: 使用 C 语言(CPython)实现的函数,如 len 或 time.strftime。
  • 内置方法: 使用 C 语言实现的方法,如 dict.get。
  • 方法: 在类的定义体中定义的函数。
  • 类: 调用类时会运行类的 __new__ 方法创建一个实例,然后运行 __init__ 方法,初始
    化实例,最后把实例返回给调用方。因为 Python 没有 new 运算符,所以调用类相当于调
    用函数。
  • 类的实例: 如果类定义了 __call__ 方法,那么它的实例可以作为函数调用。
  • 生成器函数: 使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象。

用户定义的可调用类型

任何python对象都可以表现得像函数, 只需要实现__call__方法。

  1. class BingoCage:
  2. def __init__(self, items):
  3. self._items = list(items)
  4. random.shuffle(self._items)
  5. def pick(self):
  6. try:
  7. return self._items.pop()
  8. except IndexError:
  9. raise LookupError('pick from empty BingoCage')
  10. def __call__(self):
  11. return self.pick()

此时, bingo.picl()的快捷方式是bingo()

函数内省

与用户定义的常规类一样,函数使用 __dict__ 属性存储赋予它的用户属性。

用户定义的函数的属性

名称 类型 说明
__annotations__ dict 参数和返回值的注解
__call__ methodwrapper 实现 () 运算符;即可调用对象协议
__closure__ tuple 函数闭包,即自由变量的绑定(通常是 None )
__code__ code 编译成字节码的函数元数据和函数定义体
__defaults__ tuple 形式参数的默认值
__get__ method-wrapper 实现只读描述符协议
__globals__ dict 函数所在模块中的全局变量
__kwdefaults__ dict 仅限关键字形式参数的默认值
__name__ str 函数名称
__qualname__ str 函数的限定名称,如 Random.choice

函数注解

  1. def clip(text:str, max_len:'int > 0'=80) -> str:

注解表达式可以是任何类型。注解中最常用的类型是类(如 str 或 int)和字符串(如 'int > 0')

python 解释器不会对这些注解添加任何的语义。它们不会被类型检查,运行时跟没有加注解之前的效果也没有任何差距。Python 对注解所做的唯一的事情是,把它们存储在函数的 __annotations__ 属性(一个字典)里。

返回多个值的函数

返回多个值,实际上是先创建了一个元组然后返回的。

functools.partial()来减少某个函数的参数个数

partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。

  1. def spam(a, b, c, d):
  2. print(a, b, c, d)
  3. from functools import partial
  4. s1 = partial(spam, 1) # a = 1
  5. s1(2, 3, 4) # 输出: 1,2 3,4
  6. s2 = partial(spam, d=42) # d = 42
  7. s2(1, 2, 3) # 输出: 1,2 3,4
  8. s3 = partial(spam, 1, 2, d=42) # a = 1, b = 2, d = 42
  9. s3(3) # 输出: 1, 2,3, 42

将单方法的类转化成函数

大多数情况下,可以使用闭包来将单个方法的类转换成函数。

  1. class UrlTemplate:
  2. def __init__(self, template):
  3. self.template = template
  4. def open(self, **kwargs):
  5. return urlopen(self.template.format_map(kwargs))

该类可以转化成:

  1. def urltemplate(template):
  2. def opener(**kwargs):
  3. return urlopen(template.format_map(kwargs))
  4. return opener

python 闭包

带额外状态信息的回调函数

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注