@songying
2018-07-16T01:59:08.000000Z
字数 2336
阅读 1301
python函数
来源: 流畅的python 第5章
在Python中,所有函数都是一等函数。
python中,函数就是对象。
有了一等函数,就可以使用函数式风格编程。
定义: 接受函数为参数,或者把函数作为结果返回的函数是高阶函数
函数式编程中,map、filter 和 reduce是常见的高阶函数, 但如今 map、filter 和 reduce 这三个高阶函数还能见到,不过多数使用场景下都有更好的替代品。
在python3中, map, filter依旧是内置函数,但是reduce已经移到 functools模块了。
python中使用lambda来创建匿名函数。
lambda只是语法糖,与 def 语句一样,lambda 表达式会创建函数对象。
除了作为参数传给高阶函数之外,Python 很少使用匿名函数。
- 编写注释,说明 lambda 表达式的作用。
- 研究一会儿注释,并找出一个名称来概括注释。
- 把 lambda 表达式转换成 def 语句,使用那个名称来定义函数。
- 删除注释。
- 用户定义的函数: 使用 def 语句或 lambda 表达式创建。
- 内置函数: 使用 C 语言(CPython)实现的函数,如 len 或 time.strftime。
- 内置方法: 使用 C 语言实现的方法,如 dict.get。
- 方法: 在类的定义体中定义的函数。
- 类: 调用类时会运行类的
__new__方法创建一个实例,然后运行__init__方法,初始
化实例,最后把实例返回给调用方。因为 Python 没有 new 运算符,所以调用类相当于调
用函数。- 类的实例: 如果类定义了
__call__方法,那么它的实例可以作为函数调用。- 生成器函数: 使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象。
任何python对象都可以表现得像函数, 只需要实现
__call__方法。
class BingoCage:def __init__(self, items):self._items = list(items)random.shuffle(self._items)def pick(self):try:return self._items.pop()except IndexError:raise LookupError('pick from empty BingoCage')def __call__(self):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 |
def clip(text:str, max_len:'int > 0'=80) -> str:
:后添加注解表达式=号之间) 和函数声明末尾:之间添加->和一个表达式。注解表达式可以是任何类型。注解中最常用的类型是类(如 str 或 int)和字符串(如 'int > 0')。
python 解释器不会对这些注解添加任何的语义。它们不会被类型检查,运行时跟没有加注解之前的效果也没有任何差距。Python 对注解所做的唯一的事情是,把它们存储在函数的 __annotations__ 属性(一个字典)里。
返回多个值,实际上是先创建了一个元组然后返回的。
functools.partial()来减少某个函数的参数个数partial() 函数允许你给一个或多个参数设置固定的值,减少接下来被调用时的参数个数。
def spam(a, b, c, d):print(a, b, c, d)from functools import partials1 = partial(spam, 1) # a = 1s1(2, 3, 4) # 输出: 1,2 3,4s2 = partial(spam, d=42) # d = 42s2(1, 2, 3) # 输出: 1,2 3,4s3 = partial(spam, 1, 2, d=42) # a = 1, b = 2, d = 42s3(3) # 输出: 1, 2,3, 42
大多数情况下,可以使用闭包来将单个方法的类转换成函数。
class UrlTemplate:def __init__(self, template):self.template = templatedef open(self, **kwargs):return urlopen(self.template.format_map(kwargs))
该类可以转化成:
def urltemplate(template):def opener(**kwargs):return urlopen(template.format_map(kwargs))return opener
