2013-05-03 7 views
7

मुझे यकीन नहीं है कि ऐसा करने का एक मानक तरीका है या नहीं। मैंने किसी ऑब्जेक्ट की सभी सामग्री को डंप करने के लिए निम्न फ़ंक्शन को कार्यान्वित किया है। यह रिकर्सिवली उप वस्तुओं डंप करना चाहिए, तो मैं InstanceType के लिए जाँच कर रहा हूँ, लेकिन यह काम नहीं करता है:रिकर्सिवली ऑब्जेक्ट

import types 

def dump_obj(obj, level=0): 
    for a in dir(obj): 
     try: 
      if type(obj.__dict__[a]) == types.InstanceType: 
       dump_obj(obj.__dict__[a], level + 2) 
      else: 
       try: 
        print " " * level + "%s -> %s" % (a, obj.__dict__[a]) 
       except: 
        pass 
     except: 
      pass 

मैं अगर एक तत्व ही एक वस्तु है यह पुष्टि कैसे करूं?

जो मैं वास्तव में चाहता हूं वह निम्नलिखित है। यह देखते हुए:

class B: 
    def __init__(self): 
    self.txt = 'bye' 

class A: 
    def __init__(self): 
    self.txt = 'hello' 
    self.b = B() 

a = A() 

dump_obj(a) 

मैं निम्नलिखित उत्पादन हैं:

txt -> hello 
    txt -> bye 
+0

सब कुछ पायथन में एक वस्तु है। – Matthias

+0

ठीक है: मैं कैसे सत्यापित कर सकता हूं कि कोई तत्व 'प्रकारों का प्रकार है। इंस्टेंस टाइप' (या जो कुछ भी आवश्यक है), ताकि मैं रिकर्सन ट्रिगर कर सकूं? – dangonfast

उत्तर

2

यह हमेशा isinstance(x, y) बजाय type(x) == y उपयोग करने के लिए बेहतर है।

चूंकि सबकुछ पाइथन में एक वस्तु है, इसलिए isinstance(attr, object) करने का अर्थ नहीं है, क्योंकि (मुझे लगता है) यह हमेशा सच होता है।

आपकी सर्वश्रेष्ठ शर्त कुछ प्रकारों को "ब्लैकलिस्ट" करना है। उदाहरण के लिए, आप जांचते हैं कि यह int, float, str, unicode, list, dict, set, ... के अलावा है, तो आप गहरे जाते हैं, अन्यथा आप इसे प्रिंट करते हैं।

उदाहरण के लिए:

def dump(obj, level=0): 
    for attr in dir(obj): 
     val = getattr(obj, a) 
     if isinstance(val, (int, float, str, unicode, list, dict, set)): 
      print level*' ', val 
     else: 
      dump(val, level=level+1) 

अद्यतन: isinstance खाता विरासत में ले जाता है, इसलिए यदि आप यदि एक वस्तु एक माता पिता के वर्ग का एक उदाहरण है देखने की कोशिश है, यह सच है वापस आ जाएगी, जबकि यह नहीं जब मई प्रकार का उपयोग कर।

इस मामले में आप आदिम प्रकारों के खिलाफ परीक्षण करेंगे, इससे इस मामले में कोई फर्क नहीं पड़ता है, लेकिन सामान्य रूप से isinstance बेहतर है।

इस उदाहरण देखें:

>>> class A(object): pass 
... 
>>> class B(A): pass 
... 
>>> a, b = A(), B() 
>>> type(a) 
<class '__main__.A'> 
>>> type(a) == A 
True 
>>> type(b) 
<class '__main__.B'> 
>>> type(b) == B 
True 
>>> type(b) == A 
False 
>>> 

आप बाहर docs

+0

धन्यवाद, मैंने ऐसा कुछ करने के लिए समाप्त किया, लेकिन 'प्रकार() == 'का उपयोग कर। क्या आप विस्तार से बता सकते हैं कि 'isinstance' का उपयोग करना बेहतर क्यों है? – dangonfast

+0

आप सही हैं, और मेरा उदाहरण सरलीकृत था: वास्तव में मैं मानक पुस्तकालयों से जटिल वस्तुओं को डंप करना चाहता हूं, इसलिए आपकी चेतावनी प्रासंगिक है। दूसरी ओर, 'गेटैटर' विधियों और अन्य चीजों को भी लौटाता है, जो अनंत रिकर्सन का कारण बनता है। – dangonfast

+0

@gonvaled ओह अच्छा लगता है :) – jadkik94

5

आपका कोड मेरे लिए काम करता है, सिवाय इसके कि कोई बात बिगड़ आदेश (में मुद्रित करने के जाँच कर सकते हैं भीतरी पहले है, जो क्या मैं वास्तव में होगा रिकर्सन के साथ उम्मीद करें)।

तो, मैं क्रम बदल (और __dict__ से अधिक isinstance() इस्तेमाल किया बार-बार दोहराना के साथ ही):

import types 

def dump_obj(obj, level=0): 
    for key, value in obj.__dict__.items(): 
     if not isinstance(value, types.InstanceType): 
      print " " * level + "%s -> %s" % (key, value) 
     else: 
      dump_obj(value, level + 2) 

class B: 
    def __init__ (self): 
    self.txt = 'bye' 

class A: 
    def __init__(self): 
    self.txt = 'hello' 
    self.b = B() 

a = A() 

dump_obj(a) 

txt -> hello 
    txt -> bye 
+0

यह सरल उदाहरणों के लिए काम करता था, लेकिन एक जटिल वस्तु के लिए, इसमें कुछ डेटा गायब था उप-वस्तुओं। – wisbucky

5

यह पैदा करता है रिकर्सिवली किसी भी वस्तु और सभी उप-वस्तुओं डंप हो जाएगा। अन्य उत्तरों ने सरल उदाहरणों के लिए काम किया, लेकिन जटिल वस्तुओं के लिए, वे कुछ डेटा खो रहे थे।

import jsonpickle # pip install jsonpickle 
import json 

serialized = jsonpickle.encode(obj) 
print json.dumps(json.loads(serialized), indent=2) 

संपादित करें: यदि आप वाईएएमएल प्रारूप का उपयोग करते हैं, तो यह आपके उदाहरण के करीब भी होगा।

import yaml # pip install pyyaml 
print yaml.dump(yaml.load(serialized), indent=2) 
+2

यह स्वीकार्य उत्तर होना चाहिए –

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