2014-01-07 32 views
0

我有一個裝飾器方法來檢查傳遞給函數的參數類型。將當前類傳遞給裝飾函數

def accepts(*types): 
    def check_accepts(f): 
     assert len(types) == f.func_code.co_argcount 
     def new_f(*args, **kwds): 
      for (a, t) in zip(args, types): 
       assert isinstance(a, t), \ 
         "arg %r does not match %s" % (a,t) 
      return f(*args, **kwds) 
     new_f.func_name = f.func_name 
     return new_f 
    return check_accepts 

現在,在一個類(在classA.py),我想一個方法只接受同一類的參數:

class ClassA: 
    @accepts(WHATTOPUTHERE) 
    def doSomething(otherObject): 
     # Do something 

在其他類我就可以把ClassA到位WHATTOPUTHERE,但在classA.py內,ClassA未知。我如何才能將當前課程傳遞給@accepts()函數?

+0

對不起,我不知道你是什麼意思。這不是我的意圖,不是。你能解釋爲什麼會發生? – RemiX

+0

呃,想一想,這不會發生在這裏;你已經重新實現了相同的類型檢查方法*已經*在Python 2中執行;強制'self'屬於當前類的相同類型或子類。但它看起來好像你沒有考慮到'args [0]'是'self'在這裏。 –

回答

1

使用裝飾的功能,根據版本和類定義後應用它:

class ClassA: 
    def doSomething(otherObject): 
     # Do something 
ClassA.doSomething = accepts(ClassA)(ClassA.doSomething) 

另一種方式是寫一個Metaclass,將一流的創作後自動應用此:

class Meta(type): 

    def __new__(cls, clsname, bases, dct): 
     fields = ('doSomething',) #Fields on which you want to apply the decorator 
     for name, val in dct.items(): 
      if name in fields: 
       dct[name] = accepts(cls)(val) 
     return type.__new__(cls, clsname, bases, dct) 


class ClassA(object): 
    __metaclass__ = Meta 
    def doSomething(otherObject): 
     pass 

而不是手動操作new_f.func_name = f.func_name,請使用functools.wraps。這也將保存像docstring,參數列表等東西。

from functools import wraps 
def accepts(*types): 
    def check_accepts(f): 
     print "inside" 
     assert len(types) == f.func_code.co_argcount 
     @wraps(f) 
     def new_f(*args, **kwds): 
+0

完美地工作,謝謝! – RemiX