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-1
和2*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/