@songying
2018-07-16T09:59:08.000000Z
字数 2336
阅读 1100
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 partial
s1 = partial(spam, 1) # a = 1
s1(2, 3, 4) # 输出: 1,2 3,4
s2 = partial(spam, d=42) # d = 42
s2(1, 2, 3) # 输出: 1,2 3,4
s3 = partial(spam, 1, 2, d=42) # a = 1, b = 2, d = 42
s3(3) # 输出: 1, 2,3, 42
大多数情况下,可以使用闭包来将单个方法的类转换成函数。
class UrlTemplate:
def __init__(self, template):
self.template = template
def open(self, **kwargs):
return urlopen(self.template.format_map(kwargs))
该类可以转化成:
def urltemplate(template):
def opener(**kwargs):
return urlopen(template.format_map(kwargs))
return opener