Python编程functools模块

1.partial函数的使用

functools.partial 通过包装手法,允许我们 “重新定义” 函数签名1.
例:

给两条形如y=m*x+b的直线,给定起点l和终点r取他们之间的整数作为输入判断y值的大小并计数,若y1>y2的点多,则输出为first,若y1<y2的点多,则输出为second,若一样多则输出为any

For line1 = [1, 2], line2 = [2, 1], l = 0 and r = 2, the output should be
twoLines(line1, line2, l, r) = "any";

For line1 = [1, 2], line2 = [2, 1], l = -1 and r = 2, the output should be
twoLines(line1, line2, l, r) = "first";

For line1 = [1, 2], line2 = [2, 1], l = 0 and r = 3, the output should be
twoLines(line1, line2, l, r) = "second"
示例代码如下:
from functools import partial

def line_y(m, b, x):
    return m * x + b

def twoLines(line1, line2, l, r):
    line1_y = partial(line_y,line1[0],line1[1])
    line2_y = partial(line_y,line2[0],line2[1])
    balance = 0
    for x in range(l, r + 1):
        y1 = line1_y(x)
        y2 = line2_y(x)
        if y1 > y2:
            balance += 1
        elif y1 < y2:
            balance -= 1
    if balance > 0:
        return "first"
    if balance < 0:
        return "second"
    return "any"

2.函数的组合使用

例如:
f = "math.log10", g = "abs" and x = -100

则输出为:`simpleComposition(f, g, x) = 2`

示例代码:

def compose(f, g):
    return lambda x:f(g(x))

def simpleComposition(f, g, x):
    return compose(eval(f), eval(g))(x)

3.函数列表重新组成新的函数

Input:
    functions = ["abs", "math.sin", "lambda x: 3 * x / 2"]
    x = 3.1415
Output:
    functionsComposition(functions, x) = 1

示例代码如下:

def compose(functions):
    return reduce(lambda f, g: lambda x: f(g(x)), functions)

def functionsComposition(functions, x):
    return compose(map(eval, functions))(x)

4.Python中装饰器的使用

对列表第2*i-12*i个数求和,i从1开始。
示例:

Input
    vines = [1, 2, 3, 4, 5] and n = 2
Output:
    mergingVines(vines, n) = [10, 5]
    1 :[1+2,3+4,5]
    2 :[3+7,5]=[10,5]

示例代码:

def mergingVines(vines, n):
    def nTimes(n):
        def apply_n_times(f):
            if n == 0:
                return lambda x: x
            else:
                return lambda x: f(nTimes(n - 1)(f)(x))
        return apply_n_times

@nTimes(n)
def sumOnce(vines):
    res = [vines[i] + vines[i + 1] for i in range(0, len(vines) - 1, 2)]
    if len(vines) % 2 == 1:
        res.append(vines[-1])
    return res

return sumOnce(vines)

主要是python中代参数装饰器的使用2.


5.functools中的warps

先看下,手动实现的Python装饰器,

import functools

def log(f):
    def warp(*args, **kargs):
        print(f"before log")
        return f(*args, **kargs)
    return warp

@log
def test_warp():
    print("test warp")

print(test_warp.__name__)
# warp

可见在注解中,修改了原函数的签名,在有些情况下这种操作是不适当的,如日志输出时的函数名,更希望输出的是源函数的名。

import functools

def log(f):
    @functools.wraps(f)
    def wrap(*args, **kargs):
        print(f"before log")
        return f(*args, **kargs)
    return wrap

@log
def test_wrap():
    print("test warp")
print(test_wrap.__name__)
# test_wrap

可见,使用functools.wraps函数可以拷贝原函数的属性信息。warps源码中通过使用partial函数复制了原函数的信息。

装饰器介绍参考(七)Python中的装饰器

  • Refer

1 http://www.wklken.me/posts/2013/08/18/python-extra-functools.html

2 http://gohom.win/2015/10/25/pyDecorator/

3.https://zhuanlan.zhihu.com/p/45535784

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值