2009-11-23 15 views
40

मुझे सजावटी के साथ डॉकस्ट्रिंग का उपयोग करने में समस्या है। निम्न उदाहरण को देखते हुए:पायथन सजावट हैंडलिंग डॉकस्ट्रिंग

def decorator(f): 
    def _decorator(): 
     print 'decorator active' 
     f() 
    return _decorator 

@decorator 
def foo(): 
    '''the magic foo function''' 
    print 'this is function foo' 

help(foo) 

अब मदद की उम्मीद के रूप में मेरे foo की docstring प्रदर्शित नहीं करता है, यह पता चलता है:

Help on function _decorator in module __main__: 

_decorator() 

डेकोरेटर के बिना, मदद सही है:

Help on function foo in module __main__: 

foo() 
    the magic foo function 

मुझे पता है कि समारोह foo सजावट द्वारा लपेटा गया है, और इसलिए फ़ंक्शन ऑब्जेक्ट foo फ़ंक्शन नहीं है। लेकिन उम्मीद के अनुसार डॉकस्ट्रिंग (और सहायता) प्राप्त करने का एक अच्छा समाधान क्या है?

उत्तर

62

उपयोग functools.wraps() डेकोरेटर की विशेषताओं को अद्यतन करने के:

from functools import wraps 

def decorator(f): 
    @wraps(f) 
    def _decorator(): 
     print 'decorator active' 
     f() 
    return _decorator 

@decorator 
def foo(): 
    '''the magic foo function''' 
    print 'this is function foo' 

help(foo) 

इसके अलावा functools के लिए Standard Library documentation देखते हैं।

+0

यह काम नहीं करता है अगर 'foo' कोई तर्क लेता है - वे जो भी '_decorator' उपयोग करता है उसे बदल दिया जाता है। यह एक समस्या है, खासकर जब आप अपने सजावटी को '* args, ** kwds' लेना चाहते हैं। मैं 'functools.wraps' का उपयोग करके डॉकस्ट्रिंग को सही करने का कोई तरीका नहीं ढूंढ पाया। –

+3

@ स्कॉट ग्रिफिथ्स: 'foo' तर्क लेने के बावजूद डॉकस्ट्रिंग अभी भी सही होगा। हालांकि, 'help (foo) '' _decorator' की पैरामीटर सूची प्रदर्शित करेगा, क्योंकि यह वास्तव में' foo' फ़ंक्शन को प्रतिस्थापित करता है। अगर आप सजावटी लिख रहे हैं तो इस बारे में कोई अच्छा तरीका नहीं है जो '* args, ** kwargs' का उपयोग करके मनमाने ढंग से तर्क लेते हैं, लेकिन मेरे लिए महत्वपूर्ण बात यह है कि डॉकस्ट्रिंग को बरकरार रखा जाता है। पैरामीटर विवरण हमेशा स्पष्टता के लिए डॉकस्ट्रिंग में निर्दिष्ट किया जा सकता है। –

+0

अतिरिक्त जानकारी के लिए धन्यवाद। मैं हाल ही में सजाए गए कार्यों के लिए मदद विवरण को सही करने में असफल रहा हूं - यह मामलों की एक बहुत ही खराब स्थिति है, लेकिन मैं कठिनाई को समझता हूं क्योंकि सजाए गए कार्य में पूरी तरह से अलग हस्ताक्षर हो सकते हैं। फिर भी, एक रास्ता होना चाहिए ... :) –

12

मैं एक समाधान नहीं मिला है, लेकिन अगर यह वास्तव में अच्छा है पता नहीं है:

def decorator(f): 
    def _decorator(): 
     print 'decorator active' 
     f() 
    _decorator.__name__=f.__name__ 
    _decorator.__doc__=f.__doc__ 
    return _decorator 

_decorator.__name__=f.__name__ साथ हिस्सा एक छोटा सा घृणित लगता है ... आप क्या सोचते हैं?

+4

वास्तव में यह है (लगभग?) :) – thomas

+2

: बस यह सुनिश्चित करें कि @decoratordef decorator(f) के रूप में एक ही लाइन पर इंडेंट किया गया है। यह बिल्कुल कहता है कि आप इसे क्या कहना चाहते हैं। "मैं चाहता हूं कि इस समारोह का नाम '_decorator' के बजाय 'myfunction' हो।" – jcdyer

-5

यह शायद अब थोड़ा पुराना है, लेकिन यह तुम कैसे करते है। यह मेरे लिए घृणित नहीं लगती है functools.wraps वास्तव में क्या करना

from functools import wraps 

def decorator(f): 
    @wraps(f) 
    def _decorator(): 
     print 'decorator active' 
     return f() 
    return _decorator 

@decorator 
def foo(): 
    '''the magic foo function''' 
    print 'this is function foo' 

help(foo) 
+8

यह पहले से ही स्वीकृत उत्तर को प्रतिबिंबित कर रहा है। –

संबंधित मुद्दे