我是python和裝飾器的新手,並且難於編寫一個裝飾器,它不僅報告了args和kwargs,而且還保留了未改變的默認kwargs。python裝飾器顯示傳遞和默認kwargs
這是我到目前爲止。
def document_call(fn):
def wrapper(*args, **kwargs):
print 'function %s called with positional args %s and keyword args %s' % (fn.__name__, args, kwargs)
return fn(*args, **kwargs)
return wrapper
@document_call
def square(n, trial=True, output=False):
# kwargs are a bit of nonsense to test function
if not output:
print 'no output'
if trial:
print n*n
square(6) # with this call syntax, the default kwargs are not reported
# function square called with positional args (6,) and keyword args {}
# no output
36
square(7,output=True) # only if a kwarg is changed from default is it reported
# function square called with positional args (7,) and keyword args {'output': True}
49
「問題」是這個裝飾報道說,在呼叫方通過,但沒有報告在廣場定義中定義的默認kwargs的ARGS。報告kwargs的唯一方法是如果它們從默認值改變,即傳遞給方形調用。
對於我如何獲得方形定義中的kwargs的任何建議也有報道?
後續檢查建議,這有助於我下面的解決方案後編輯。我改變了位置參數的輸出以包含他們的名字,因爲我認爲它使得輸出更容易理解。
import inspect
def document_call(fn):
def wrapper(*args, **kwargs):
argspec = inspect.getargspec(fn)
n_postnl_args = len(argspec.args) - len(argspec.defaults)
# get kwargs passed positionally
passed = {k:v for k,v in zip(argspec.args[n_postnl_args:], args[n_postnl_args:])}
# update with kwargs
passed.update({k:v for k,v in kwargs.iteritems()})
print 'function %s called with \n positional args %s\n passed kwargs %s\n default kwargs %s' % (
fn.__name__, {k:v for k,v in zip(argspec.args, args[:n_postnl_args])},
passed,
{k:v for k,v in zip(argspec.args[n_postnl_args:], argspec.defaults) if k not in passed})
return fn(*args, **kwargs)
return wrapper
這是一個很好的學習經驗。看到針對同一問題的三種不同解決方案是很好的。感謝Answerers!
@Martijn,謝謝;我已經閱讀了答案的前兩行,並且會消失,學習所有關於檢查的內容,並且看看我想出了什麼。然後會回來看看如何真正做到這一點;-) – user5799671