2016-06-12 6 views
0

この質問への拡張です:https://stackoverflow.com/a/37568895/2290820 オプションで機能上のデコレータを有効または無効にする方法。これらの行でどのように再帰的な関数呼び出しでデコレータが呼び出されるようにするには?

、私は再帰呼び出しで呼び出されますデコレータを作るために、このような何かを思い付いた:再帰関数にデコレータを試して

def deco(f): 
    def fattr(attr): 
     f.attr = attr 
     def closure(*args): 
      f(*args) 
     f.unwrap = f 
     f.closure = closure 
     return f 
    return fattr 

@deco 
def printa(x): 
    if x > 1: 
     print x 
     return printa(x-1) 
    else: 
     print x 
    return 

printa({1:1})(5) 

# do the same call w/o deocorator 
def finta(x): 
    if x > 1: 
     print x 
     return finta(x-1) 
    else: 
     print x 
    return 

finta(5) # this works 

。明らかに、printa再帰バージョンは、それがすべき方法ではありません。

私は

g = printa({1:1}) 
g.closure(5) 

はデコレータのオプションをオンまたはそのオプションを使用しないように行うことができます。とにかく、デザインの良し悪しにかかわらず、再帰呼び出しでデコレータを呼び出すにはどうすればいいですか?

+0

私はこれがトピックから投票された理由を知りません。これはとても話題です! – user2290820

答えて

1

decoには、最初の再帰呼び出し後に引数を「食べる」というf.attr = attrという割り当てがあります。あなたはこのようにあなたの再帰呼び出しを修正する必要があります:

def deco(f): 
    def fattr(attr): 
     f.attr = attr 
     def closure(*args): 
      f(*args) 
     f.unwrap = f 
     f.closure = closure 
     return f 
    return fattr 

@deco 
def printa(x): 
    if x > 1: 
     print x 
     return printa(None)(x-1) # None will be assigned to f.attr 
    else: 
     print x 
    return 

printa({1:1})(5) 

5 
4 
3 
2 
1 
+0

はい、完璧です。私はそれを試そうとしていた。 – user2290820

関連する問題