函数对象

一等对象

  • 在运行时创建
  • 能赋值给变量或数据结构中的元素
  • 能作为参数传给函数
  • 能作为函数的返回结果
    整数、字符串、字典都是一等对象。

高阶函数

接受函数为参数,或者把函数作为结果返回的函数是高阶函数;
最为人熟知的高阶函数有map、filter、reduce、apply;
sum和reduce的通用思想是把某个操作连续应用到序列的元素上,累计之前的结果,把一系列的值归约成一个值

函数内省

使用dir(factorial)可以探知factorial具有哪些属性;

函数注解

eg:

def choose_slot_type_and_bin_type(current_item:Item.ItemInfo,sku_type:Item.ItemCatagory)->int:

函数编程式的包

operstor模块

算术运算符函数

在函数编程中,经常需要把算术运算符当做函数使用。例如,不使用递归计算阶乘,求和可以使用sum,但求积没有这样的函数。

from functools import reduce
def fact(n):
    return reduce(lambda a,b:a*b, range(1,n+1))

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

from functools import reduce
from operator import mul
def fact(n):
    return reduce(mul, range(1,n+1))

operstor模块包含的部分函数

print([name for name in dir(operator) if not name.startswith('_')])
输出:
['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul', 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub', 'truediv', 'truth', 'xor']

以i开头、后面是另一个运算符的那些名称(如iadd、iand等),对应的是增量赋值运算符(如+=、&=等)。如果第一个参数是可变的,那么这些运算符函数会就地修改它;否则,作用与不带i的函数一样,直接返回运算结果。
operator模块中还有一类函数,能替代从序列中取出元素或读取对象属性的lambda表达式:因此,itemgetter和attrgetter其实会自行构建函数。

itemgetter函数

用itemgetter排序一个元组列表:

metro_data = [
    ('Tokyo', 'JP', 36, (35, 139)),
    ('Delhi NCR', 'IN', 21, (28, 77)),
    ('Mexico City', 'MX', 20, (19, -99)),
    ('Sao Paulo', 'BR', 19, (-23, -46)),
]
from operator import itemgetter
for city in sorted(metro_data, key = itemgetter(1)):
    print(city)
输出(根据元祖的第二个值进行排序):
('Sao Paulo', 'BR', 19, (-23, -46))
('Delhi NCR', 'IN', 21, (28, 77))
('Tokyo', 'JP', 36, (35, 139))
('Mexico City', 'MX', 20, (19, -99))

把多个参数传给itemgetter,它构建的函数会返回提取的值构成的元组

metro_data = [
    ('Tokyo', 'JP', 36, (35, 139)),
    ('Delhi NCR', 'IN', 21, (28, 77)),
    ('Mexico City', 'MX', 20, (19, -99)),
    ('Sao Paulo', 'BR', 19, (-23, -46)),
]
from operator import itemgetter
cc_name = itemgetter(1,0)
for city in metro_data:
    print(cc_name(city))
输出:
('JP', 'Tokyo')
('IN', 'Delhi NCR')
('MX', 'Mexico City')
('BR', 'Sao Paulo')

attrgetter与itemgetter作用类似,它创建的函数根据名称提取对象的属性。如果把多个属性名传给attrgetter,它也会返回提取的值构成的元组。此外,如果参数名中包含.(点号),attrgetter会深入嵌套对象,获取指定的属性:

from collections import namedtuple
from operator import attrgetter

metro_data = [
    ('Tokyo', 'JP', 36, (35, 139)),
    ('Delhi NCR', 'IN', 21, (28, 77)),
    ('Mexico City', 'MX', 20, (19, -99)),
    ('Sao Paulo', 'BR', 19, (-23, -46)),
]

LatLong = namedtuple('LatLong','lat long')
Metropolis = namedtuple('Metropolis','name cc pop coord')
metro_areas = [Metropolis(name,cc,pop,LatLong(lat,long)) for name,cc,pop,(lat,long) in metro_data]
print(metro_areas[0])
print(metro_areas[0].coord.lat)
name_lat = attrgetter('name','coord.lat')
for city in sorted(metro_areas,key = attrgetter('coord.lat')):
    print(name_lat(city))
输出:
Metropolis(name='Tokyo', cc='JP', pop=36, coord=LatLong(lat=35, long=139))
35
('Sao Paulo', -23)
('Mexico City', 19)
('Delhi NCR', 28)
('Tokyo', 35)

methodcaller函数

它的作用与attrgetter和itemgetter类似,它会自行创建函数。methodcaller创建的函数会在对象上调用参数指定的方法

from operator import methodcaller

s = 'The time has come'
upcase = methodcaller('upper')
print(upcase(s))
hiphenate = methodcaller('replace',' ','-')
print(hiphenate(s))
输出:
THE TIME HAS COME
The-time-has-come

functools.partial冻结参数

functools.partial这个高阶函数用于部分应用一个函数。部分应用是指,基于一个函数创建一个新的可调用对象,把原函数的某些参数固定。使用这个函数可以把接受一个或多个参数的函数改编成需要回调的API,这样参数更少;
使用partial把一个两参数函数改编成需要单参数的可调用对象:

from operator import mul
from functools import partial

triple = partial(mul,3)
print(triple(7))  # 21
print(list(map(triple,range(1,10))))  # [3, 6, 9, 12, 15, 18, 21, 24, 27]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值