functools.partial 的例子
functools.partial
使用已填写一个或多个参数的函数创建新的版本。
新版本的功能是基于旧版本的。
接下来,我将使用代码来解释这是如何工作的,而不是深入解释他的代码。
首先,假设创建一个明确执行幂运算的函数。通过这种方式,我们可以在任何数量上获得 平方,立方和其他次方的操作。其实下面的函数就是模仿了Python的内置pow() 函数
pow()
def power(base, exponent): return base ** exponent
现在,如果想要具有power()函数的平方和立方函数呢?当然,我们可以这样做:
power()
def square(base): return power(base, 2)def cube(base): return power(base, 3)
当然没有问题,但是如果我们想要创建15或20个power()函数变体呢?他们中的1000个呢?不用说,写这么多重复的代码是烦人的。这是partial发挥作用的时候了。我们可以使用partial重写我们的square和cube函数,并使用py.test测试它是否成功 :
from functools import partialsquare = partial(power, exponent=2)cube = partial(power, exponent=3)def test_partials(): assert square(2) == 4 assert cube(2) == 8
大家可以自行尝试。刚才,我们使用了function.partial 函数创建了一个新的函数(某种程度上)。我会用更多的测试来证明partial函数创建的是一个幂函数:
def test_partial_docs(): assert square.keywords == {"exponent": 2} assert square.func == power assert cube.keywords == {"exponent": 3} assert cube.func == power
使用循环,让我们构建并测试10个自定义power()函数:
def test_power_partials(): # 准备一个存储新函数的列表 power_partials = [] for x in range(1, 11): # 创建新的函数 f = partial(power, exponent=x) # 将新的函数加入列表中 power_partials.append(f) # 当然我们也可以使用列表解析式来完成上面的工作 # [partial(power, exponent=x) for x in range(1, 11)] # 测试第一个新函数 assert power_partials[0](2) == 2 # 测试第五个新函数 assert power_partials[4](2) == 32 # 测试第十个新函数 assert power_partials[9](2) == 1024
我相信上面的例子大家应该都能看懂吧~接下来,我们来看看在类中如何应用partial:
from six import add_metaclass class PowerMeta(type): def __init__(cls, name, bases, dct): # 在这里,我生成50个新函数 for x in range(1, 51): # 这里使用了python的反射 setattr( # cls就是我们这个类了 cls, # 给新函数取一个名字 "p{}".format(x), # 新函数的具体定义 partial(power, exponent=x) ) super(PowerMeta, cls).__init__(name, bases, dct)@add_metaclass(PowerMeta)class PowerStructure(object): pass
接下来,就来测试下我们的PowerStructure类:
def test_power_structure_object(): p = PowerStructure() # p2的10次方 assert p.p2(10) == 100 # p5的2次方 assert p.p5(2) == 32 # p50的2次方 assert p.p50(2) == 1125899906842624
看起来不错,对吧?但是,我们可以做的更好!
感谢元类的强大功能,我们不需要实例化PowerStructure类!
def test_power_structure_class(): # 这里就能感受到元类的强大了吧! assert PowerStructure.p2(10) == 100 assert PowerStructure.p5(2) == 32 assert PowerStructure.p50(2) == 1125899906842624
functools.partials,容易造成代码含义不清晰
目前我开了2个主群,我邀请了一些我的BAT伙伴前来助阵。定期也会在群里组织抽奖、送书等活动。更有各种资源分享。
目前2个主群都以过百,想要加入的小伙伴,可以加我微信,我拉你们,或者公众号回复关键“关注作者”。(本周日,微信号就可以恢复使用,想入群的小伙伴加我微信后,不用担心哦,周日统一拉群~)
文章有问题?点此查看未经处理的缓存