2012-04-06 11 views
6

में गतिशील डॉकस्ट्रिंग बनाना मैं गतिशील रूप से कुछ कक्षा परिभाषाएं उत्पन्न करने की कोशिश कर रहा हूं (सी ++ एक्सटेंशन को लपेटने के लिए)। निम्नलिखित वर्णनकर्ता ठीक काम करता है सिवाय इसके कि जब मैं मदद() का उपयोग करके किसी क्षेत्र के लिए डॉकस्ट्रिंग तक पहुंचने का प्रयास करता हूं, तो यह क्षेत्र के बजाए वर्णनकर्ता के लिए डिफ़ॉल्ट दस्तावेज देता है।पायथन डिस्क्रिप्टर

class FieldDescriptor(object): 
    def __init__(self, name, doc='No documentation available.'): 
     self.name = name 
     self.__doc__ = doc 

    def __get__(self, obj, dtype=None): 
     if obj is None and dtype is not None: 
      print 'Doc is:', self.__doc__ 
      return self 
     return obj.get_field(self.name) 

    def __set__(self, obj, value): 
     obj.set_field(self.name, value) 

class TestClass(object): 
    def __init__(self): 
     self.fdict = {'a': None, 'b': None} 

    def get_field(self, name): 
     return self.fdict[name] 

    def set_field(self, name, value): 
     self.fdict[name] = value 

fields = ['a', 'b'] 
def define_class(class_name, baseclass): 
    class_obj = type(class_name, (baseclass,), {}) 
    for field in fields: 
     setattr(class_obj, field, FieldDescriptor(field, doc='field %s in class %s' % (field, class_name))) 
    globals()[class_name] = class_obj 


if __name__ == '__main__': 
    define_class('DerivedClass', TestClass) 
    help(DerivedClass.a) 
    help(DerivedClass) 
    v = DerivedClass() 
    help(v.a) 

"अजगर test.py" प्रिंट: लेकिन जब मैं मदद (classname) करते हैं, यह docstring वर्णनकर्ता के लिए पारित पुन: प्राप्त करता

 
Doc is: field a in class DerivedClass 
Help on FieldDescriptor in module __main__ object: 

class FieldDescriptor(__builtin__.object) 
| Methods defined here: 
| 
| __get__(self, obj, dtype=None) 
| 
| __init__(self, name, doc='No documentation available.') 
| 
| __set__(self, obj, value) 
| 
| ---------------------------------------------------------------------- 
| Data descriptors defined here: 
| 
| __dict__ 
|  dictionary for instance variables (if defined) 
| 
| __weakref__ 
|  list of weak references to the object (if defined) 

Doc is: field a in class DerivedClass 
Doc is: field b in class DerivedClass 
Help on class DerivedClass in module __main__: 

class DerivedClass(TestClass) 
| Method resolution order: 
|  DerivedClass 
|  TestClass 
|  __builtin__.object 
| 
| Data descriptors defined here: 
| 
| a 
|  field a in class DerivedClass 
| 
| b 
|  field b in class DerivedClass 
| 
| ---------------------------------------------------------------------- 
| Methods inherited from TestClass: 
| 
| __init__(self) 
| 
| get_field(self, name) 
| 
| set_field(self, name, value) 
| 
| ---------------------------------------------------------------------- 
| Data descriptors inherited from TestClass: 
| 
| __dict__ 
|  dictionary for instance variables (if defined) 
| 
| __weakref__ 
|  list of weak references to the object (if defined) 

Help on NoneType object: 

class NoneType(object) 
| Methods defined here: 
| 
| __hash__(...) 
|  x.__hash__() hash(x) 
| 
| __repr__(...) 
|  x.__repr__() repr(x) 

किसी भी विचार एक descriptor.__doc__help(class.field) के लिए कैसे प्राप्त कर सकते हैं ? और क्या इसे बाईपास करने का कोई तरीका है और दस्तावेज़ के लिए डॉक स्ट्रिंग को स्टोर करने के दौरान दस्तावेज़ के लिए गेटर फ़ंक्शन की तरह कुछ है?

चाहते:

class FieldDescriptor(object): 
    def __init__(self, name, doc='No documentation available.'): 
     self.name = name 
     self.__doc__ = doc 

    def __get__(self, obj, dtype=None): 
     if obj is None and dtype is not None: 
      print 'Doc is:', self.__doc__ 
      return self 
     return obj.get_field(self.name) 

    def __set__(self, obj, value): 
     obj.set_field(self.name, value) 

    # This is what I'd like to have 
    def __doc__(self, obj, dtype): 
     return dtype.generate_docstring(self.name) 

अद्यतन: असल में मैं __get__ की इस परिभाषा के साथ शुरू किया:

def __get__(self, obj, dtype=None): 
    return obj.get_field(self.name) 

इस के साथ समस्या यह थी कि जब मैंने कहा:

help(DerivedClass.a) 

अजगर एक अपवाद फेंक दिया जो दर्शाता है कि मैंपर कॉल करने की कोशिश कर रहा था। इस प्रकार help()__get__ विधि obj=None और dtype=DerivedClass के साथ विधि को कॉल कर रहा है। यही कारण है कि मैंने फील्डडिस्क्रिप्टर उदाहरण वापस करने का फैसला किया जब obj = कोई नहीं और dtype! = कोई नहीं। मेरी इंप्रेशन help(xyz)xyz.__doc__ प्रदर्शित करने का प्रयास करती है। उस तर्क से, यदि __get__descriptor_instance देता है, तो descriptor_instance.__doc__ सहायता() द्वारा मुद्रित किया जाना चाहिए, जो पूरे वर्ग [help(DerivedClass)] के मामले में है, लेकिन एकल फ़ील्ड [help(DerivedClass.a)] के लिए नहीं है। जो वस्तु वर्णनकर्ता के __get__ विधि द्वारा दिया है - - अजगर कोष्ठकों के अंदर अभिव्यक्ति की गणना करता है -

+0

मुझे यकीन है कि यह सब वहाँ है, लेकिन क्या आप यह स्पष्ट कर सकते हैं कि कौन सी कॉल आपको गलत सहायता आउटपुट दे रही हैं? कोड पढ़ने के द्वारा आपको अपेक्षित अनुमान लगाने का बहुत अधिक प्रयास है। – alexis

+0

जैसा कि jsbueno ने इंगित किया है, यह मदद (DerivedClass.a) है जो फ़ील्ड के लिए प्रलेखन के बजाय वर्णनकर्ता के लिए प्रलेखन प्रदर्शित करता है (वर्णनकर्ता में सहेजा गया .__ doc__)। – subhacom

उत्तर

1

क्या पर चला जाता है कि आप help(DerivedClass.a) का अनुरोध करते हैं और उन्हें उस वस्तु पर मदद (docstring सहित) की खोज पर।

डायनामिक डॉकस्ट्रिंग पीढ़ी समेत इस काम को करने का एक तरीका है, वांछित दस्तावेज़ स्ट्रिंग वाली गतिशील रूप से जेनरेट की गई वस्तु को दोबारा शुरू करने के लिए __get__ विधि रखना है। लेकिन इस ऑब्जेक्ट को मूल रूप से एक उचित प्रॉक्सी ऑब्जेक्ट होने की आवश्यकता होगी, और आपके कोड पर कुछ ओवरहेड बनाएगा - और बहुत से विशेष मामले।

वैसे भी, इसे काम करने के लिए एकमात्र तरीका यह है कि आप __get__ द्वारा लौटाई गई वस्तुओं को संशोधित करना चाहते हैं, ताकि वे व्यवहार करें जैसे आप उन्हें चाहें।

ईद का सुझाव है कि अगर आप सभी की मदद में चाहते हैं की तरह आप कर रहे हैं के बारे में जानकारी का एक सा है, हो सकता है आप चाहते हैं वस्तुओं एक वर्ग है कि एक __repr__ विधि (बल्कि सिर्फ एक __doc__ स्ट्रिंग से परिभाषित की जा करने के लिए अपने __get__ से लौटे)।

+0

'__repr__' दृष्टिकोण काम नहीं करता है। इसके अलावा, यह कक्षा के दस्तावेज़ीकरण को मुद्रित करता है जो '__repr__' लागू करता है। सामान्य वर्णनकर्ताओं के बजाय गुणों का उपयोग करना, लेकिन यह स्थिर रूप से डॉकस्ट्रिंग को संग्रहीत करने से पीड़ित है। पीडीबी के साथ सहायता फ़ंक्शन का पता लगाने से पता चला कि Pyyoc.hehelp() 'में परीक्षण पायथन में परिभाषित वर्णक के अज्ञेयवादी हैं, हालांकि वे सी एपीआई का उपयोग करके परिभाषित संपत्ति और विभिन्न वर्णनकर्ताओं का ख्याल रखते हैं। वैसे भी आपके इनपुट के लिए धन्यवाद, यह मुझे अन्य तरीकों का प्रयास करने के लिए प्रोत्साहित किया। – subhacom

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