python第五章课后答案加注释_《fluent python》第五章 一等函数

一等对象

编程语言理论家把“一等对象”定义为满足下述条件的程序实体:在运行是创建

能赋值给变量或数据结构中的元素

能作为参数传给函数 - 能作为函数的返回结果

把函数当作对象

函数都是function类的实例,类的方法是method类的实例(虽然经常会把方法称为函数)

def fun():

pass

class Foo:

def bar(self):

pass

print(type(fun))

>>>

print(type(Foo().bar))

>>>

高阶函数

接受函数为参数或者把函数作为结果返回的函数称为高阶函数。

在函数式编程范式中,最为人熟知的高阶函数有map(), filter(), reduce()

all()和any()

all(iterable), 如果iterable的每个值都为True,返回True any(iterable), 如果iterable存在一个值为True,返回True

匿名函数

使用lambda关键字创建匿名函数,格式为lambda [arg1 [,arg2,.....argn]]:expression,匿名函数的定义体中不能赋值,不能使用while和try语句。

我十分不喜欢用匿名函数,基本没有用过,即使是用高阶函数需要传递函数作为参数时,也是额外用def语句编写函数,所以一直对lambda理解不到位。

匿名函数这样理解:将arg x作为参数传递给expression,得到结果后返回。

Lundh提出的lambda表达式重构秘笈: - (1)编写注释,说明lambda表达式的作用 - (2)研究注释,用一个名称来概括注释 - (3)把lambda表达式改写成def,使用那个名称作为函数名 - (4)删除注释

可调用对象

使用callable()函数可判断是否为可调用对象。python中有7种可调用对象: - 用户使用def和lambda创建的函数 - 内置函数,使用C语言(CPython)实现的函数,如len或time.strftime - 使用C语言实现的方法,如dict.get - 方法,在类的定义体中定义的函数 - 类,调用类时会运行__new__方法创建一个实例,python没有new运算符,所以调用类相当于调用函数 - 定义了__call__()类的实例 - 生成器函数,使用yield关键字的函数或方法

L = [abs, str, 13]

print([callable(x) for x in L])

>>>[True, True, False]

函数内省

函数内省(function introspection)是在运行时进行的一种对象检测机制,用来查看某个对象内部信息,如类的type类型、属性、方法、事件等等。

(内省: 文言,意思是查看内部情况。华夏特色的翻译,恕我直言,把第一个叫这个名字的人拉出去斩了)

python中使用dir()可以获得对象的各种信息。

def fun():

pass

print(dir(fun))

>>>['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

获取关于参数的信息

以我目前水平不能理解作者讲的这些内容有什么作用

函数注解

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

return ''

函数声明中的各个参数可以在:之后增加注解表达式。如果参数有默认值,注解放在参数名和=号之间。如果想注解返回值,在)和函数声明末尾的:之间添加->和一个表达式。这个表达式可以是任何类型,在上面的例子中是str

注解不会做任何处理,只是存储在函数的__annotations__属性(一个字典)中

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

return ''

print(clip.__annotations__)

>>>{'text': , 'max_len': 'int > 0', 'return': }

支持函数式编程的包

from functools import reduce, mul

def fact1(n):

return reduce(lambda a, b: a*b, range(1, n+1))

def fact2(n):

return reduce(mul, range(1, n+1))

operator模块为多个算术运算符提供了对应的函数,从而避免编写lambda a, b: a*b这种平凡的匿名函数

itemgetter和attrgetter

operator模块中还有一类函数,能替代从序列中取出元素或读取对象属性的lambda表达式,如itemgetter和attrgetter

# 将students表按第二个属性升序排列

from operator import itemgetter

students = [

('xiao ming', 77, 180),

('lao wang', 75, 185),

('xiao qing', 100, 183),

]

res = sorted(students, key=itemgetter(1))

print(res)

attrgetter类似

methodcaller

methodcaller创建的函数会在对象上调用参数指定的方法

from operator import methodcaller

s = 'I am a pupil'

f = methodcaller('replace', ' ', '-')

print(f(s))

>>>I-am-a-pupil

functools.partial

from operator import mul

from functools import partial

f = partial(mul, 3)

print(f(7))

>>>21

固定第一个参数为3, 传入7则结果为21

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值