簡體   English   中英

Python:使用相同的裝飾器裝飾__call__和普通函數?

[英]Python: decorate __call__ and ordinary function with the same decorator?

在Python 2.6-2.7中是否可以使用相同的裝飾器執行以下任務:

class ComplextCallableObject(object):
    @wrap_me
    def __call__(self, a1, a2):
        pass

@wrap_me
def simple_function(a1, a2):
    pass

ComplextCallableObject.__call__simple_function都具有相同的args,但__call__也具有第一個arg的self wrap_me裝飾器中,我需要訪問被包裝的函數args。

不幸的是,在定義時(本例中為類塊),除了命名約定之外,代碼無法告訴函數如何使用。 稍微修改你的例子:

class ComplextCallableObject(object):
    @wrap_me
    def __call__(self, a1, a2):
        pass #...

@wrap_me
def simple_function(tgt, a1, a2):
    pass

ComplextCallableObject.anInstanceMethod = simple_function
ComplextCallableObject.anClassMethod = classmethod(simple_function)
ComplextCallableObject.aStaticMethod = staticmethod(simple_function)

在這種情況下, simple_function正在實現一個采用目標和兩個參數的函數,一個采用兩個參數的實例方法,一個采用兩個參數的類方法,一個采用目標和兩個參數的靜態方法。 但是這些用法在定義函數之后才會被綁定。 staticmethodclassmethod返回不同的對象類型,因此如果需要,您可以區分它們。

如果您確實想使用約定,則可以檢查函數的第一個參數名稱以查看它是否為self

def wrap_me(fn):
    names = fn.func_code.co_varnames
    if names and names[0]=='self':
        print 'looks like an instance method'
    else: print 'looks like a function'
    return fn
def wrap_me(*args):
    a1, a2 = args if len(args) == 2 else args[1:]
    ...

當然,如果在類方法上調用了wrap_me ,則需要修改返回的函數以獲取self參數。

順便說一句,假設你實際上沒有在你正在裝飾的函數中使用self ,它應該是一個靜態的方法。

這可能相當愚蠢,但也可能適用於最簡單的情況:

In [1]: def wrap_me(func):
   ...:     def wrapped(*args):
   ...:         print 'arg1 is', args[-2]
   ...:         print 'arg2 is', args[-1]
   ...:         func(*args)
   ...:     return wrapped
   ...:
In [2]: class ComplexCallableObject(object):
   ...:     @wrap_me
   ...:     def __call__(self, a1, a2):
   ...:         print 'class object called'
   ...:
In [3]: @wrap_me
   ...: def simple_function(a1, a2):
   ...:     print 'function called'
   ...:
In [4]: simple_function('A', 'B')
arg1 is A
arg2 is B
function called
In [5]: o = ComplexCallableObject()
In [6]: o('A', 'B')
arg1 is A
arg2 is B
class object called

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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