python偏函数

https://zhuanlan.zhihu.com/p/47124891

和装饰器一样,它可以扩展函数的功能,但又不完成等价于装饰器。通常应用的场景是当我们要频繁调用某个函数时,其中某些参数是已知的固定值,通常我们可以调用这个函数多次,
但这样看上去似乎代码有些冗余,而偏函数的出现就是为了很少的解决这一个问题。举一个很简单的例子,比如我就想知道 100 加任意数的和是多少,通常我们的实现方式是这样的:

# 第一种做法:
def add(*args):
    return sum(args)

print(add(1, 2, 3) + 100)
print(add(5, 5, 5) + 100)

# 第二种做法
def add(*args):
    # 对传入的数值相加后,再加上100返回
    return sum(args) + 100

print(add(1, 2, 3))  # 106
print(add(5, 5, 5))  # 115 

看上面的代码,貌似也挺简单,也不是很费劲。但两种做法都会存在有问题:
第一种,100这个固定值会返回出现,代码总感觉有重复;
第二种,就是当我们想要修改 100 这个固定值的时候,我们需要改动 add 这个方法。下面我们来看下用 parital 怎么实现:

from functools import partial

def add(*args):
    return sum(args)

add_100 = partial(add, 100)
print(add_100(1, 2, 3))  # 106

add_101 = partial(add, 101)
print(add_101(1, 2, 3))  # 107


参数:
func: 需要被扩展的函数,返回的函数其实是一个类 func 的函数
*args: 需要被固定的位置参数
**kwargs: 需要被固定的关键字参数  # 如果在原来的函数 func 中关键字不存在,将会扩展,如果存在,则会覆盖

  1. 理解代码
# 同样是刚刚求和的代码,不同的是加入的关键字参数
def add(*args, **kwargs):
    # 打印位置参数
    for n in args:
        print(n)
    print("-"*20)
    # 打印关键字参数
    for k, v in kwargs.items():
       print('%s:%s' % (k, v))
    # 暂不做返回,只看下参数效果,理解 partial 用法

# 普通调用
add(1, 2, 3, v1=10, v2=20)
"""
1
2
3
--------------------
v1:10
v2:20
"""

# partial
add_partial = partial(add, 10, k1=10, k2=20)
add_partial(1, 2, 3, k3=20)
"""
10
1
2
3
--------------------
k1:10
k2:20
k3:20
"""

add_partial(1, 2, 3, k1=20)
"""
10
1
2
3
--------------------
k1:20
k2:20
"""
  1. 应用代码
from functools import partial
basetwo = partial(int, base=2)
basetwo.__doc__ = 'Convert base 2 string to an int.'

res = basetwo('10')
print(res)  # 2
print(int('10',base=2))  # 2 
  1. partial实现代码类似如下:
def partial(func, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = keywords.copy()
        newkeywords.update(fkeywords)
        return func(*args, *fargs, **newkeywords)
    return newfunc
posted @ 2021-06-09 17:11  该显示昵称已被使用了  阅读(49)  评论(0编辑  收藏  举报