【问题标题】:How to (re)define function with complex argument如何(重新)定义具有复杂参数的函数
【发布时间】:2017-03-05 10:19:54
【问题描述】:

我在 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 函数。

【问题讨论】:

  • 您到底想问什么?如果您想编写一个包装该方法并应用YInvert 的函数,只需...执行此操作。或者写一个 invertAllY 方法,也许,它可以获取 (x, y) 坐标列表并返回 (x, y') 反转列表。
  • 我在问如何编写这样一个函数LineNew 来包装YInvert。特别是我如何管理一个函数在括号中作为参数。此外,我不知道如何传递 strokefill 等参数集。
  • 听起来你想为特定参数修补很多函数。你想要一个通用的解决方案吗?
  • “括号里的东西” 只是一个tuple。您提到的 “参数集”keyword 参数。对于 SO 问题,如何写东西相当广泛。

标签: python function arguments svgwrite


【解决方案1】:

这是一种装饰器方法。坐标检测不是很智能,您可能需要稍微磨练一下:

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)

【讨论】:

  • 感谢您的热心帮助。
猜你喜欢
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 2018-09-14
相关资源
最近更新 更多