2010-07-23 16 views
6

पर पाइथन विरासत पेड़ को रिकर्सिवली चलाना मैं पाइथन में कुछ क्रमबद्धता/deserialization कोड लिख रहा हूं जो कुछ JSON से विरासत पदानुक्रम पढ़/लिखेंगे। सटीक संरचना तब तक ज्ञात नहीं होगी जब तक अनुरोध भेजा नहीं जाता है।रन-टाइम

तो, मुझे लगता है कि पाइथन वर्ग पदानुक्रम को उत्सर्जित करने के लिए और फिर, पेड़ के माध्यम से वापस रास्ते पर, सही स्थापित करने के लिए सुरुचिपूर्ण समाधान माना जाता है, सही स्थापित करें एक पायथन मूल प्रकार में मूल्य।

E.g., 

A 
| 
|\ 
| \ 
B C 

अगर मैं अपने "आत्मनिरीक्षण" बी पर नियमित कहते हैं, यह एक dict कि उनके मूल्यों, साथ ही बी के चर और उनके मूल्यों के लिए एक के चर के सभी से एक मानचित्रण शामिल लौटना चाहिए।

जैसा कि अब यह खड़ा है, मैं B.__slots__ या B.__dict__ देख सकता हूं, लेकिन मैं केवल वहां से बी के परिवर्तनीय नाम खींच सकता हूं।

मैं केवल बी के बाद __slots__/__dict__ कैसे प्राप्त करूं? (या सी)।

मुझे पता है कि अजगर सीधे सी की तरह कास्टिंग का समर्थन नहीं करता ++ & उसके वंश do-

उत्तर

11

आप type.mro() विधि का उपयोग कर विधि संकल्प आदेश खोजने की कोशिश हो सकती है।

class A(object): 
     pass 

class B(A): 
     pass 

class C(A): 
     pass 

a = A() 
b = B() 
c = C() 

>>> type.mro(type(b)) 
[<class '__main__.B'>, <class '__main__.A'>, <type 'object'>] 
>>> type.mro(type(c)) 
[<class '__main__.C'>, <class '__main__.A'>, <type 'object'>] 

या

>>> type(b).mro() 

संपादित करें: मैं सोच रहा था अगर आप इस तरह कुछ करना चाहता था ...

>>> A = type("A", (object,), {'a':'A var'}) # create class A 
>>> B = type("B", (A,), {'b':'B var'})  # create class B 
>>> myvar = B() 

def getvars(obj): 
    ''' return dict where key/value is attribute-name/class-name ''' 
    retval = dict() 
    for i in type(obj).mro(): 
     for k in i.__dict__: 
      if not k.startswith('_'): 
       retval[k] = i.__name__ 
    return retval 

>>> getvars(myvar) 
{'a': 'A', 'b': 'B'} 

>>> for i in getvars(myvar): 
    print getattr(myvar, i) # or use setattr to modify the attribute value 

A Var 
B Var 
+0

हम्म, जो बताता है कि मुझे लौटाई गई सूची के सदस्यों में से एक से उछाल की आवश्यकता होगी। मुझे यकीन नहीं है कि पायथन में ऐसा कैसे करें। –

+0

आह, मुझे लगता है कि मैं वास्तव में समझ में नहीं आया कि आप क्या खोज रहे थे। मैंने यह स्पष्ट करने का प्रयास किया कि मैंने आपके प्रश्न को एक संपादन के साथ कैसे व्याख्या किया। –

+0

'[local_variables_of (i()) के लिए मैं टाइप (ओ)। एमआरओ() [: - 1]] 'मैं जिस समाधान के साथ आया था वह था। 'local_variables_of' चेक करता है __slots__ और __dict__ और एटीआर नामों की एक सूची देता है। –

2

शायद आप स्पष्ट कर सकते यदि आप एक के लिए क्या देख रहे थोड़ा आगे?

फिलहाल आपका वर्णन पाइथन का वर्णन नहीं करता है।

b = B() 

आप क्रम के शब्दकोश को देखें, तो:

class A(object) : 
...  def __init__(self) : 
...    self.x = 1 
class B(A) : 
...  def __init__(self) : 
...    A.__init__(self) 
...    self.y = 1 

फिर एक क्रम उदाहरण के रूप में बनाया जा सकता है: मान लेते हैं कि अपने उदाहरण में ए, बी और सी कक्षाओं के नाम हैं चलो ऑब्जेक्ट तब इसके अपने चर के संबंधित चर और चर के बीच कोई भेद नहीं है। उदाहरण के लिए तो: dir (ख)

[ ... snip lots of double-underscores ... , 'x', 'y'] 

तो अपने सवाल का सीधा जवाब है कि यह पहले से ही उस तरह काम करता है है, लेकिन मुझे लगता है कि आप के लिए बहुत उपयोगी नहीं है। जो दिखाता है वह विधियों के रूप में नहीं है क्योंकि वे कक्षा के नामस्थान में प्रविष्टियां हैं, जबकि चर वस्तु के नामस्थान में हैं। यदि आप सुपरक्लास में विधियों को ढूंढना चाहते हैं तो पहले के जवाब में वर्णित mro() कॉल का उपयोग करें और फिर सूची में कक्षाओं के नामस्थानों को देखें।

जबकि मैं जेएसओएन क्रमबद्ध करने के सरल तरीकों के लिए चारों ओर देख रहा था, मुझे अचार मॉड्यूल में कुछ दिलचस्प चीजें मिलीं। एक सुझाव यह है कि आप हाइराक्रैची को पार करने के लिए खुद को लिखने के बजाए ऑब्जेक्ट्स को अचार/अनपिक करना चाहते हैं। अचार आउटपुट एक ASCII धारा है और आपके लिए जेएसओएन को आगे और पीछे परिवर्तित करना आसान हो सकता है। पीईपी 307 में कुछ शुरुआती बिंदु हैं।

अन्य सुझाव __reduce__ विधि पर एक नज़र डालना है, उन वस्तुओं पर आज़माएं जिन्हें आप सीरियलाइज़ करना चाहते हैं क्योंकि यह वही हो सकता है जो आप खोज रहे हैं।

+0

मैं जो काम कर रहा था वह अन्य वस्तुओं में बना वस्तुओं के साथ एक वर्ग पदानुक्रम deserializing है। सदस्य वस्तुओं को एक ताना में स्थानांतरित करने की आवश्यकता है। यह 'जेसन' में धक्का दिया जाता है। जब मैं __slots__ या __dict__ चर के विश्लेषण कर रहा था, मैंने देखा कि उनके पास पैरेंट वैरिएबल नहीं हैं। न ही उनके पास एक पॉइंटर-टू-पैरेंट है। –