2017-03-05 135 views
-1

我在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函數即可。

+1

你到底在問什麼?如果你想編寫一個函數來封裝這個方法並應用'YInvert',那麼......就這樣做。或者寫一個'invertAllY'方法,或許,它可以取得(x,y)座標列表並返回(x,y')倒列列表。 – jonrsharpe

+0

我在問如何編寫這樣一個包裝'YInvert'的函數'LineNew'。特別是我怎樣才能管理一個函數作爲括號中的參數。此外,我不知道如何傳遞諸如「stroke」和「fill」這樣的參數集合。 – fales

+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) 
+0

謝謝你的協助。 – fales

+0

不客氣。 –