-1

svgwrite在 Python 中使用该库,并且因为 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在正确的位置添加函数。

4

1 回答 1

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)
于 2017-03-05T10:39:35.307 回答