其實這個問題由來已久,早在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...