2012-11-09 47 views
2

所以我一直堅持這個一段時間,圖我會要求一些建議。我試圖創建一個修飾器,可以修改函數docstring,允許可選參數或無,並且是簽名保留。另外,這些都可以完成。甚至獲得三個中的兩個。維護簽名的Python裝飾器,允許修改文檔字符串,並允許可選參數

下面的示例似乎修改了文檔字符串,並允許可選參數或無。但是,這種方法不保留簽名。

from functools import wraps 
def thisDecorator(*targs, **tkwargs): 
    def internalFunc(func): 
     func.__doc__ = "Added this... {0}".format(func.__doc__) 
     @wraps(func) 
     def wrapper(*args, **kwargs): 
      return func(*args, **kwargs) 
     return wrapper 
    if len(targs) == 1 and callable(targs[0]): 
     return internalFunc(targs[0]) 
    else: 
     return internalFunc 

我看了一下裝飾模塊,做維護簽名,但我似乎無法修改的文檔字符串。

所有的幫助感激

回答

0

也許我不完全理解你的要求,但是這似乎是爲我工作:

class myDeco: 
    def __init__(self, f): 
     self.f = f 
     if f.__doc__: 
      self.__doc__ = 'great doc: ' + f.__doc__ 
     else: 
      self.__doc__ = 'ooohh, no doc' 
    def __call__(self, *args, **kwargs): 
     print "decorator args and kwargs: {0}, {1}".format(args, kwargs) 
     self.f(*args, **kwargs) 

@myDeco 
def test1(): 
    """test1 doc""" 
    print 'test1' 

@myDeco 
def test2(a, b): 
    print 'test2: {0}, {1}'.format(a,b) 

@myDeco 
def test3(a, *args): 
    print "test3: {0}, {1}".format(a, args) 

@myDeco 
def test4(a, *args, **kwargs): 
    print "test4: {0}, {1}, {2}".format(a, args, kwargs) 


print test1.__doc__ 
print test2.__doc__ 
print test3.__doc__ 
print test4.__doc__ 

test1() 
test2(1,2) 
test3(1,2,3) 
test4(1,2,3, foo=4, bar=5) 

簽名被保留,該文檔被修改,可選參數是允許的。輸出是:

great doc: test1 doc 
ooohh, no doc 
ooohh, no doc 
ooohh, no doc 
decorator args and kwargs:(), {} 
test1 
decorator args and kwargs: (1, 2), {} 
test2: 1, 2 
decorator args and kwargs: (1, 2, 3), {} 
test3: 1, (2, 3) 
decorator args and kwargs: (1, 2, 3), {'foo': 4, 'bar': 5} 
test4: 1, (2, 3), {'foo': 4, 'bar': 5} 
+0

感謝您的回覆。在這種情況下,使用裝飾模塊將會發揮作用。但不是在我想的情況下。將裝飾器放在內部函數上將保留傳遞給該函數的簽名。 –

3

通過添加一個裝飾器到內部包裝,這將保留函數簽名。

from functools import wraps 
from decorator import decorator 

def thisDecorator(*targs, **tkwargs): 
    def internalFunc(func): 
     func.__doc__ = "Added this... {0}".format(func.__doc__) 
     @wraps(func) 
     def wrapper(func, *args, **kwargs): 
      return func(*args, **kwargs) 
     return decorator(wrapper, func) 
    if len(targs) == 1 and callable(targs[0]): 
     return internalFunc(targs[0]) 
    else: 
     return internalFunc