Bottle的外掛程式與view裝飾器衝突問題

2021-07-06 02:27:05 字數 1904 閱讀 4672

其實這個問題由來已久,早在2023年就有人在bottle那報告過,但是因為python的inspec庫本身的問題,它的wraps函式不能保留被包裝函式的引數資訊,所以一直不能徹底解決。

問題大致是這樣:

@view("index")

def get_index():

return dict(a="a")

上面是乙個典型的使用view decorator的請求響應函式。如果我們要在這個請求中加入sqlite外掛程式,則**就是這樣:

from bottle.ext.sqlite import plugin

@view("index")

def get_index(db):

a = some_func(db)

return dict(a=a)

通過閱讀sqlite外掛程式原始碼(所有類似的外掛程式都是類似這樣實現的),可以發現它是通過inspect庫的getargspec來取得原始函式的引數資訊,如果其中含有db這個引數,就提供乙個sqlite連線給這個引數,否則就略過。

網上看到的建議(不知道算不算官方建議)有兩個方法:

def get_index(db):

a = some_func(db)

return dict(a=a)

這樣一來就把view decorator放到外掛程式route裡去了,sqlite外掛程式裡的inspect.getargspec()就可以取得get_index的引數資訊。

另一種方法是用template引數,如:

def get_index(db):

a = some_func(db)

return dict(a=a)

這種方法比上面一種更簡單,實際是使用了bottle內建的乙個叫template的外掛程式(詳見bottle原始碼)。

不過因為我並不用預設模板,一直都是用mako,要用這兩種方法的話都有點麻煩(尤其是template方式,參考下面的兩段**),所以以前都是用自己寫的乙個類似內建template外掛程式的模板外掛程式(用法與使用預設模板的template引數方式差不多)。

from bottle import mako_view as view

def get_index(db):

a = some_func(db)

return dict(a=a)

# or

from bottle import makotemplate

def get_index(db):

a = some_func(db)

return dict(a=a)

之所以現在來提這個舊問題,是因為在今年的pycon上聽了孔令開的乙個演講提到引數處理的 事情,就請教了他一下,他提供了乙個給bottle打補丁的方案,在自定義的wraps裡額外儲存乙份引數資訊。群裡還有人提供了一些代替 functools.wraps的方案,可以保留函式引數資訊。不過我研究了一番以後,覺得都還是不夠好。

孔兄的方案雖然比較簡單,但是因為額外儲存的引數資訊並不會被inspect.getargspec()所獲得,所以除了自己寫的外掛程式以外,別的外掛程式還是取不到引數資訊。

而第三方wraps的方法雖然可以解決其它外掛程式問題,但是卻需要依賴第三方庫,而且同樣需要對bottle打補丁以替換原來的wraps,但最讓我不能接受的原因是——這些第三方庫對此的實現方式是類似eval的方法。

看來bottle之所以三年沒有解決這個問題,的確是因為這並不是個容易解決的問題。歸根到底還是要怪functools.wraps沒有解決函式引數資訊保留的問題。

最後說乙個剛剛看到的解決方法:使用python3的inspect.signature(),這個可以取得wraps之前的函式引數資訊。但是遺憾的是python2.x不支援…

但我會在我自己寫的外掛程式裡換上這個,至少可以為py3環境提供更方便的使用。

推送到[go4pro.org]

幾個wordpress必裝的外掛程式

1.收集表單資訊傳送到指定網域名稱郵箱 contact form 7 contact form cfdb7 wp mail smtp 2.加速wordpress訪問,減少waiting ttfb時間 wp super cache 3.收集訂閱郵箱 email subscribers 4.xml xm...

View的測量與繪製

通過measurespec這乙個類,就可以獲取view的測量模式和view想要繪製的大小。measurespec類,是乙個32位的int值,前兩位為測量的模式,測量的模式有三種 exactly,at most,unspecified view類預設的測量view方式為onmeasure 且只支援ex...

關於旋轉(view的旋轉以及上面電池條選裝的方向)

1.view.transform一般是view的旋轉,拉伸移動等屬性,類似view.layer.transform,區別在於view.transform是二維的,也就是使用仿射的辦法通常就是帶有字首cgaffinetransform的類 可以到api文件裡面搜尋這個字首的所有類 而view.laye...