[英]Python: wrapping recursive functions
如何包裝遞歸函數,包括遞歸調用? 例如,給定foo
和wrap
:
def foo(x):
return foo(x - 1) if x > 0 else 1
def wrap(f):
def wrapped(*args, **kwargs):
print "f was called"
return f(*args, **kwargs)
return wrapped
wrap(foo)(x)
只會在第一次調用時輸出"f was called"
。 遞歸調用仍然解決foo()
。
我不介意猴子修補,或在內部戳。 我不打算將這個代碼添加到下一個核彈頭處理程序中,所以即使這是一個壞主意,我也想實現這個效果。
編輯 :例如,修補foo.func_globals
以覆蓋foo.__name__
工作? 如果它總是這樣,我應該注意任何副作用?
如果您使用包裝器函數作為裝飾器,它可以工作。
def wrap(f):
def wrapped(*args, **kwargs):
print "f was called"
return f(*args, **kwargs)
return wrapped
@wrap
def foo(x):
return foo(x - 1) if x > 0 else 1
原因是在您的示例中,您只調用一次wrap
函數的結果。 如果您將它用作裝飾器,它實際上將模塊命名空間中的foo
定義替換為裝飾函數,因此其內部調用將解析為包裝版本。
使用類而不是函數包裝函數:
>>> def foo(x):
... return foo(x-1) if x > 0 else 1
...
>>> class Wrap(object):
... def __init__(self, f): self.f = f
... def __call__(self, *args, **kwargs):
... print "f called"
... return self.f(*args, **kwargs)
...
>>> foo = Wrap(foo)
>>> foo(4)
f called
1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.