2013-08-20 63 views
4

在這裏有很多關於如何檢測Python裝飾器是否使用參數或不帶參數的答案。它們通常是這樣的:具有可選自調參數的Python裝飾器

class MyDecorator(object): 
    def __init__(self, *args): 
     if len(args) == 1 and callable(args[0]): 
     # no arguments 
     else: 
     # arguments 

但現在我有以下的用例:

@MyDecorator(lambda x:2*x) 
def foo(): 
    pass 

這是錯誤地檢測爲「無參數」的情況。

有沒有辦法來檢測這種情況?

[編輯:新增失蹤 '自我' 參數]

+2

您是否嘗試命名參數? – 2013-08-20 10:18:06

+1

@MartijnPieters我認爲這正是問題所在:如果使用一個可調參數調用,「@ MyDecorator」認爲它沒有得到任何「真實」參數,並直接作爲裝飾器工作。在其他情況下,它作爲裝飾者的創造者。而在lambda的情況下,它錯誤地做前者而不是後者。 – glglgl

+0

@Lawnmower你打算在問題中修復'__init__'這行嗎?正如你所建議的一樣,它不能用於這種方式。 – glglgl

回答

2

是的,但它仍將小幅哈克。訣竅是使用命名參數。除此之外,還沒有一種清晰的方法來區分不同的可玩玩物。

class MyDecorator(object): 
    def __init__(self, *args, **kwargs): 
     if kwargs: 
      # arguments 
      print 'got %r as arguments' 
     else: 
      callable, = args 

@MyDecorator(some_function=lambda x:2*x) 
def foo(): 
    pass 
+0

這就是我擔心的答案。我希望避免混亂。也許我讓參數成爲強制性的。然後,我不必區分大小寫(但如果忘記lambda,最終會出現非常混亂的行爲)。 – Stefan

1

__init__方法需要self參數:

class MyDecorator(object): 
    def __init__(self, *args): 
     if len(args) == 1 and callable(args[0]): 
     # no arguments 
     else: 
     # arguments 

沒有它,你總是至少一個參數,它會可調用;它是裝飾器實例。換句話說,沒有明確的self*args兩個元素,當你通過參數,它會是args[1]你想測試。

+0

啊,對不起,這只是問題的示例代碼中的一個錯誤。當然,我真的有一個'自我'。 – Stefan

+0

對,然後我誤解你在問什麼;沃爾夫很清楚。 :-) –