我在Python中使用svgwrite
库,因为svg有y轴向下,而我觉得向上移动更方便,我定义了一个函数YInvert
,这对我来说很有用。但是,每次使用svgwrite
中的函数时,我都必须使用此函数,例如:
dwg.line((xI,YInvert(yI)), (xII,YInvert(yII)), stroke='blue', stroke_width=0.1)
但是,这很不舒服。我如何重新定义函数dwg.line
(或定义一些新函数LineNew
)以自动包含YInvert
?我希望论证的形式相同,我的意思是我可以使用:
dwg.line((xI,yI), (xII,yII), stroke='blue', stroke_width=0.1)
或
LineNew((xI,yI), (xII,yII), stroke='blue', stroke_width=0.1)
我也用例如
dwg.circle(center=(10,YInvert(10)), r=0.2, fill='black')
所以我正在寻找适用于各种参数的东西,只需在正确的位置添加YInvert
函数。
答案 0 :(得分:2)
这是一个装饰方法。坐标检测不是很聪明,你可能想要磨练一点:
from functools import wraps
def YInvert(Y): # just for demo
return -Y
def invert_axis(f):
@wraps(f)
def g(*args, **kwds):
args = list(args)
for j, a in enumerate(args):
if isinstance(a, tuple) and len(a) == 2:
try:
args[j] = (a[0], YInvert(a[1]))
except:
pass
for k, v in kwds.items():
if isinstance(v, tuple) and len(v) == 2:
try:
kwds[k] = (v[0], YInvert(v[1]))
except:
pass
return f(*args, **kwds)
return g
演示:
@invert_axis
def f(a, b, c, d=3):
print(a, b, c, d)
f((1, 2), 3, (4, 5), d=(1, 2))
# (1, -2) 3 (4, -5) (1, -2)
这也可以应用于已经定义的函数,如库函数:
f2 = invert_axis(f2)