簡體   English   中英

Python:包裝遞歸函數

[英]Python: wrapping recursive functions

如何包裝遞歸函數,包括遞歸調用? 例如,給定foowrap

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM