partial
用于创建一个偏函数,将默认参数包装一个可调用对象,返回结果也是可调用对象。 偏函数可以固定住原函数的部分参数,从而在调用时更简单。
举一个简单的例子:
def add(a, b, c, x=1, y=2, z=3):
return sum([a, b, c, x, y, z])
print(add(1, 2, 3, x=1, y=2, z=3))
#输出
12
如果我们频繁调用此函数,并且固定传入某些参数,比如b=20, x=100,就可以使用partial来构造函数
from functools import partial
def add(a, b, c, x=1, y=2, z=3):
print(a, b, c, x, y, z)
return sum([a, b, c, x, y, z])
add_100 = partial(add, 20, x=100)
print(add_100(1, 2, y=2, z=3))
# 输出
20 1 2 100 2 3
128
在接口调用的使用也可以使用,比如传参数:ip地址或者是域名是固定的,只是后面的url不固定,此时就可以使用partial来构造接口调用函数
cmp_to_key
原来那种cmp函数的模式是每次直接给你两个元素,你返回它们的大小关系。由于排序过程中同一个元素会被拿去跟别的不同元素cmp很多次,可能会有性能问题。新的key函数这种模式并不直接比较任意两个原始元素,而是通过key函数把那些元素转换成一个个新的可比较对象,也就是元素的key,然后用元素的key代替元素去参与比较。如果元素key之间的比较操作比原始元素之间的比较操作效率高的话,那么就能提高性能。key函数的直接功能就是传入一个元素,返回一个可比较对象。如果原始元素本来就是可比较对象,比如数字、字符串,那么不考虑性能优化可以直接sort(key=lambda e: e)
例子:
class Solution:
def largestNumber(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
from functools import cmp_to_key
temp = list(map(str, nums))
print(temp)
temp.sort(key=cmp_to_key(lambda x, y: int(x+y)-int(y+x)), reverse=True)
print(temp)
return ''.join(temp if temp[0]!='0' else '0')
y = Solution()
x = y.largestNumber([3, 30, 34, 5, 9])
print(x)
lru_cache
允许我们将一个函数的返回值快速地缓存或取消缓存。 该装饰器用于缓存函数的调用结果,对于需要多次调用的函数,而且每次调用参数都相同,则可以用该装饰器缓存调用结果,从而加快程序运行。该装饰器会将不同的调用结果缓存在内存中,因此需要注意内存占用问题。
from functools import lru_cache
@lru_cache()
def a(x):
print(x)
return x+1
print(a(3))
使用缓存记录后,第一次a(3)调用,计算了数据后会进行缓存,第二次a(3)调用,因为参数相同,所以直接返回缓存的数据,第三次a(4)调用,因为参数不同,需要重新计算
singledispatch
单分发器, Python3.4新增,用于实现泛型函数。 根据单一参数的类型来判断调用哪个函数。 例如
def connect(address):
if isinstance(address, str):
ip, port = address.split(':')
elif isinstance(address, tuple):
ip, port = address
else:
print('地址格式不正确')
# 传入字符串
connect('123.45.32.18:8080')
# 传入元祖
connect(('123.45.32.18', 8080))
简单来说就是address可能是字符串,也可能是元组,那么我们就需要在函数内进行单独处理,如果这种类型很多呢?那就需要if...elif...elif...elif..esle...,写起来非常不美观,而且函数的可读性也会变差。 学过C++和Java的同学都知道函数重载,同样的函数名,同样的参数个数,不同的参数类型,实现多个函数,程序运行时将根据不同的参数类型自动调用对应的函数。python也提供了这样的重载方式
from functools import singledispatch
@singledispatch
def connect(address):
print(f'传入参数类型为:{type(address)}, 不是有效的类型')
@connect.register
def connect_str(address: str):
ip, port = address.split(':')
print(f'参数为字符串,IP是{ip}, 端口是{port}')
@connect.register
def connect_tuple(address: tuple):
ip, port = address
print(f'参数为元组,IP是{ip}, 端口是{port}')
connect('123.45.32.18:8080')
# 输出
参数为字符串,IP是123.45.32.18, 端口是8080
connect(('123.45.32.18', '8080'))
# 输出
参数为元组,IP是123.45.32.18, 端口是8080