ऑब्जेक्ट के तरीकों और विशेषताओं की पूरी सूची कैसे प्राप्त करें?


230
dir(re.compile(pattern)) 

सूचियों के तत्वों में से एक के रूप में पैटर्न वापस नहीं करता है। अर्थात् यह लौटता है:

['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']

मैनुअल के अनुसार, इसमें शामिल होना चाहिए

ऑब्जेक्ट की विशेषताओं के नाम, उसकी कक्षा की विशेषताओं के नाम, और उसके वर्ग के आधार वर्गों की विशेषताओं के बारे में।

यह भी कहता है कि

जरूरी नहीं कि सूची पूरी हो।

क्या पूरी सूची प्राप्त करने का कोई तरीका है ? मैंने हमेशा यह माना कि dir एक पूरी सूची देता है, लेकिन जाहिर है कि यह नहीं है ...

इसके अलावा: क्या केवल विशेषताओं को सूचीबद्ध करने का एक तरीका है? या केवल तरीके?

संपादित करें: यह वास्तव में अजगर में एक बग है -> माना जाता है कि यह 3.0 शाखा में तय किया गया है (और शायद 2.6 में भी)


5
dir()निरीक्षण मॉड्यूल का उपयोग करना या करना आम तौर पर इसे करने का सही तरीका है। क्या आपने reएक उदाहरण के रूप में मॉड्यूल का उपयोग किया या आप एक विशेष लक्ष्य प्राप्त करना चाहते हैं?

1
क्या आप सुनिश्चित हैं कि पैटर्न वास्तव में एक बार संकलित किए जाने वाले डेटा के रूप में रखा गया है? मैं इस धारणा के तहत था कि एक पैटर्न को संकलित करने का बिंदु दिए गए पैटर्न को पार्स करने के लिए आवश्यक परिमित राज्य ऑटोमेटा का उत्पादन करना था।
काइल स्ट्रैंड

@hop कक्षाओं से नहीं हटाया जा सकता है? उदाहरण के लिए, वे अपने पर कर सकते हैं__dir__()
ytpillai

ytpillai: सही है, लेकिन केवल पायथन 3 में। फिर भी, सवाल यह है कि क्या ऐसा वर्ग "सामान्य मामले" के अंतर्गत

जवाबों:


140

विशेषताओं की पूरी सूची के लिए, संक्षिप्त उत्तर है: नहीं। समस्या यह है कि विशेषताओं को वास्तव में getattrअंतर्निहित फ़ंक्शन द्वारा स्वीकार किए गए तर्कों के रूप में परिभाषित किया गया है । जैसा कि उपयोगकर्ता पुन: लागू कर सकता है __getattr__, अचानक किसी भी प्रकार की विशेषता की अनुमति देता है, उस सूची को उत्पन्न करने के लिए कोई संभावित सामान्य तरीका नहीं है। dirसमारोह में कुंजी देता __dict__विशेषता यानि वे सुलभ गुण अगर __getattr__विधि reimplemented नहीं है।

दूसरे प्रश्न के लिए, यह वास्तव में कोई मतलब नहीं है। दरअसल, विधियां कॉल करने योग्य विशेषताएँ हैं, अधिक कुछ नहीं। यद्यपि आप कॉल करने योग्य विशेषताओं को फ़िल्टर कर सकते हैं, और inspectमॉड्यूल का उपयोग करके वर्ग के तरीकों, विधियों या कार्यों का निर्धारण करते हैं।


1
inpect.getmembers (re.compile (पैटर्न)) एक सदस्य के रूप में पैटर्न का उत्पादन नहीं करता है, इसलिए यह शायद आंतरिक रूप से dir का उपयोग करता है ... यह बेकार है!
बार्टोज़ रैदासीस्की

अगर वे विधियां हैं, तो मैं कॉल करने योग्य का उपयोग कर सकता हूं, लेकिन यह वह बिंदु नहीं है ... मुद्दा यह है कि मैं उन विशेषताओं की सूची पर लौटने के लिए भी भरोसा नहीं कर सकता, जो वास्तव में सार्वजनिक रूप से दिखाई दे रही हैं ...
बार्टोज़ रेडास्कीस्की

2
निरीक्षण का अर्थ है "कम से कम" भरोसेमंद के रूप में डीआईआर ()। दूसरी ओर, री एक बहुत ही जटिल मॉड्यूल है

आप "सार्वजनिक रूप से दृश्यमान" द्वारा क्या परिभाषित करते हैं? यदि आप का अर्थ है "पहुँचा जा सकता है", तो वह दिए गए कारण का खोया हुआ कारण है। अन्यथा, 'डीआईआर' हमेशा गेटअटर के डिफ़ॉल्ट कार्यान्वयन के साथ सुलभ विशेषताओं की सूची लौटाता है।
पियरेबर्ड

2
dir (my_class) my_class .__ तानाशाही __ की तुलना में कुछ अलग देता है। पूर्व भी init और डॉक्टर की
JuanPi

58

यही कारण है कि __dir__()अजगर 2.6 में नई विधि जोड़ी गई है

देख:


मुझे यह त्रुटि मिलती है: >> dir __ (pyrenderdoc) Traceback (सबसे हालिया कॉल अंतिम): फ़ाइल "<string>", पंक्ति 1, में <मॉड्यूल> NameError: नाम '__dir ' परिभाषित नहीं है
मोना जलाल

__dir__ () ऑब्जेक्ट पर एक विधि है, फ़ंक्शन नहीं है - कृपया उत्तर में लिंक पढ़ें और यह
Moe

एक लाइनर सभी विशेषताओं और उनके मूल्यों को छापने के लिए:pprint({k:getattr(ojb,k) for k in obj.__dir__()})
Czechnology

21

यहाँ पियरेबर्ड और मो के उत्तरों के लिए एक व्यावहारिक जोड़ है:

  • पायथन के लिए> = 2.6 और नई शैली की कक्षाएं , dir()पर्याप्त लगती हैं।
  • के लिए पुरानी शैली कक्षाएं , हम कम से कम क्या एक कर सकते हैं मानक मॉड्यूल के अलावा: समर्थन टैब पूरा होने के लिए करता है dir(), के लिए देखो __class__, अपने लिए जाने के लिए और उसके बाद __bases__:

    # code borrowed from the rlcompleter module
    # tested under Python 2.6 ( sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) \n[GCC 4.4.3]' )
    
    # or: from rlcompleter import get_class_members
    def get_class_members(klass):
        ret = dir(klass)
        if hasattr(klass,'__bases__'):
            for base in klass.__bases__:
                ret = ret + get_class_members(base)
        return ret
    
    
    def uniq( seq ): 
        """ the 'set()' way ( use dict when there's no set ) """
        return list(set(seq))
    
    
    def get_object_attrs( obj ):
        # code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() )
        ret = dir( obj )
        ## if "__builtins__" in ret:
        ##    ret.remove("__builtins__")
    
        if hasattr( obj, '__class__'):
            ret.append('__class__')
            ret.extend( get_class_members(obj.__class__) )
    
            ret = uniq( ret )
    
        return ret

(टेस्ट कोड और आउटपुट संक्षिप्तता के लिए नष्ट हो जाती हैं, लेकिन मूल रूप से नई शैली के लिए वस्तुओं हम एक ही परिणाम है लगता है के लिए get_object_attrs()के लिए के रूप में dir(), और पुरानी शैली कक्षाओं के लिए करने के लिए मुख्य इसके अलावा dir()उत्पादन होने लगते हैं __class__विशेषता।)


9

केवल पूरक के लिए:

  1. dir()है सबसे शक्तिशाली / मौलिक उपकरण। ( सबसे अधिक )
  2. के अलावा अन्य समाधान dir()केवल उत्पादन के तरीके से निपटने का dir()तरीका प्रदान करते हैं

    दूसरे स्तर की विशेषताओं को सूचीबद्ध करना या न करना, स्वयं द्वारा शिफ्टिंग करना महत्वपूर्ण है, क्योंकि कभी-कभी आप प्रमुख अंडरस्कोर के साथ आंतरिक संस्करणों को बाहर निकालना चाह सकते हैं __, लेकिन कभी-कभी आपको __doc__डॉक्टर-स्ट्रिंग की आवश्यकता हो सकती है ।

  3. __dir__()और dir()समान सामग्री देता है।
  4. __dict__और dir()अलग हैं। __dict__अपूर्ण सामग्री देता है।
  5. महत्वपूर्ण : __dir__()कभी-कभी किसी भी उद्देश्य के लिए लेखक द्वारा एक फ़ंक्शन, मूल्य या प्रकार के साथ ओवरराइट किया जा सकता है।

    यहाँ एक उदाहरण है:

    \\...\\torchfun.py in traverse(self, mod, search_attributes)
    445             if prefix in traversed_mod_names:
    446                 continue
    447             names = dir(m)
    448             for name in names:
    449                 obj = getattr(m,name)

    TypeError: ऑब्जेक्ट के डिस्क्रिप्टर __dir__में 'object'एक तर्क की आवश्यकता होती है

    PyTorch के लेखक ने उस __dir__()विधि को संशोधित किया जिसमें तर्क की आवश्यकता होती है। यह संशोधन dir()विफल हो जाता है।

  6. यदि आप किसी वस्तु की सभी विशेषताओं को पार करने के लिए एक विश्वसनीय योजना चाहते हैं , तो याद रखें कि प्रत्येक पायथोनिक मानक को ओवरराइड किया जा सकता है और पकड़ नहीं सकता है , और प्रत्येक सम्मेलन अविश्वसनीय हो सकता है।


5

यह है कि मैं यह कैसे करते हैं, सरल कस्टम वस्तुओं के लिए उपयोगी है जिसमें आप विशेषताएँ जोड़ते रहते हैं:

दी गई किसी वस्तु के साथ obj = type("Obj",(object,),{})या बस द्वारा दिया गया:

class Obj: pass
obj = Obj()

कुछ विशेषताएँ जोड़ें:

obj.name = 'gary'
obj.age = 32

फिर, केवल कस्टम विशेषताओं के साथ एक शब्दकोश प्राप्त करने के लिए:

{key: value for key, value in obj.__dict__.items() if not key.startswith("__")}

# {'name': 'gary', 'age': 32}

अजगर 3.x में सभी विशेषताओं की सूची: {। कुंजी: कुंजी के लिए मूल्य, मूल्य में obj .__ dict __ आइटम () यदि key.startswith नहीं ( "__")} [ '_ declared_fields'] कुंजी ()।
above_c_level
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.