2009-09-22 12 views
27
class gpagelet: 
    """ 
    Holds 1) the pagelet xpath, which is a string 
      2) the list of pagelet shingles, list 
    """ 
    def __init__(self, parent): 
     if not isinstance(parent, gwebpage): 
      raise Exception("Parent must be an instance of gwebpage") 
     self.parent = parent # This must be a gwebpage instance 
     self.xpath = None  # String 
     self.visibleShingles = [] # list of tuples 
     self.invisibleShingles = [] # list of tuples 
     self.urls = [] # list of string 

class gwebpage: 
    """ 
    Holds all the datastructure after the results have been parsed 
    holds: 1) lists of gpagelets 
      2) loc, string, location of the file that represents it 
    """ 
    def __init__(self, url): 
     self.url = url    # Str 
     self.netloc = False   # Str 
     self.gpagelets = []   # gpagelets instance 
     self.page_key = ""   # str 

क्या मेरे क्लास जेसन सीरियलज़ेबल बनाने का कोई तरीका है? जो चीज मैं चिंतित हूं वह रिकर्सिव संदर्भ है।पायथन सीरियलज़ेबल ऑब्जेक्ट्स जेसन

+0

यह उत्तर उपयोगी हो सकता है: http://stackoverflow.com/a/28253689/303114 – danfromisrael

+0

आप सवाल शीर्षक बहुत अस्पष्ट है। आपको इसे सुधारना चाहिए। –

+0

एक बंद उत्तर के साथ एक ही प्रश्न: https://stackoverflow.com/a/7409526/2728644 – dasons

उत्तर

5

अप्रत्यक्ष उत्तर: JSON का उपयोग करने के बजाय, आप YAML का उपयोग कर सकते हैं, जिसमें आपको जो भी चाहिए वह करने में कोई समस्या नहीं है। (JSON अनिवार्य रूप से YAML के एक सबसेट है।)

उदाहरण:

import yaml 
o1 = gwebpage("url") 
o2 = gpagelet(o1) 
o1.gpagelets = [o2] 
print yaml.dump(o1) 

वास्तव में, YAML अच्छी तरह से चक्रीय संदर्भ आप के लिए संभालती है।

+0

[कभी भी उस डेटा को अनपिक न करें जिसे आप भरोसा नहीं करते!] (Http://nedbatchelder.com/blog/201302/war_is_peace .html) – Sardathrion

+1

दिलचस्प लेख, लेकिन इस जवाब में * कोई अनपिकलिंग * नहीं है, केवल * पिकलिंग * (यानी कोई 'लोड() ', लेकिन' डंप() ')। – EOL

+1

दरअसल लेकिन यह ध्यान में रखना उचित है। इसके अलावा, क्यों तुम कुछ जब तक आप इसे बाद में उपयोग करने के लिए योजना बनाई अचार होगा? ... दरअसल – Sardathrion

46

अपनी खुद की एनकोडर और विकोडक, जो return __dict__

जैसे जैसे बहुत आसान हो सकता है लिखें यहाँ पूरी तरह से पुनरावर्ती वृक्ष संरचना डंप करने के लिए एक एनकोडर है, आप इसे बढ़ाने या के रूप में यह अपनी खुद की उद्देश्य के लिए है का उपयोग कर सकते

import json 

class Tree(object): 
    def __init__(self, name, childTrees=None): 
     self.name = name 
     if childTrees is None: 
      childTrees = [] 
     self.childTrees = childTrees 

class MyEncoder(json.JSONEncoder): 
    def default(self, obj): 
     if not isinstance(obj, Tree): 
      return super(MyEncoder, self).default(obj) 

     return obj.__dict__ 

c1 = Tree("c1") 
c2 = Tree("c2") 
t = Tree("t",[c1,c2]) 

print json.dumps(t, cls=MyEncoder) 

यह प्रिंट

{"childTrees": [{"childTrees": [], "name": "c1"}, {"childTrees": [], "name": "c2"}], "name": "t"} 

आप इसी तरह एक विकोडक लिख सकते हैं लेकिन वहाँ आप करेंगे किसी भी तरह से यह पहचानने की आवश्यकता है कि यह आपकी वस्तु है या नहीं, तो यदि आवश्यक हो तो भी आप एक प्रकार भी डाल सकते हैं।

+2

इससे मेरी मदद की। धन्यवाद। :) –

+1

सरलजसन के लिए प्रलेखन स्पष्ट रूप से कहता है कि आपको TypeError को बढ़ाने के लिए JSONEncoder.default() को कॉल करना चाहिए, इसलिए मुझे लगता है कि आपके raise को उस कॉल के साथ प्रतिस्थापित करना बेहतर होगा। – slacy

+0

या इससे भी बेहतर, अपने स्वयं के '[सरल] json.JSONEncoder' उप-वर्ग को कार्यान्वित करें और उस संस्करण के साथ' डिफ़ॉल्ट 'विधि को ओवरराइट करें जो आपके ऑब्जेक्ट्स का क्रमिक प्रतिनिधित्व प्रस्तुत करता है या अन्य सभी प्रकारों के लिए' JSONEncoder.default' को कॉल करता है। Http://docs.python.org/library/json.html#json.JSONEncoder देखें। –

15

jsonpickle जीत के लिए!

(बस यही सवाल था ... जेसन पिकल रिकर्सिव/नेस्टेड ऑब्जेक्ट ग्राफ के साथ-साथ चक्रीय ऑब्जेक्ट ग्राफ़ के लिए शॉर्ट सर्किट को संभालता है)।

+12

[कभी unpickle नहीं डेटा पर आपको विश्वास नहीं करते हैं!] (Http://nedbatchelder.com/blog/201302/war_is_peace.html) – Sardathrion

1

इसके लिए मेरा समाधान 'dict' वर्ग का विस्तार करना और कक्षाओं के तरीकों को ओवरराइड करके अपडेट/अनुमत गुणों के आसपास जांच करना था।

class StrictDict(dict): 
    required=set() 
    at_least_one_required=set() 
    cannot_coexist=set() 
    allowed=set() 
    def __init__(self, iterable={}, **kwargs): 
     super(StrictDict, self).__init__({}) 
     keys = set(iterable.keys()).union(set(kwargs.keys())) 
     if not keys.issuperset(self.required): 
      msg = str(self.__class__.__name__) + " requires: " + str([str(key) for key in self.required]) 
      raise AttributeError(msg) 
     if len(list(self.at_least_one_required)) and len(list(keys.intersection(self.at_least_one_required))) < 1: 
      msg = str(self.__class__.__name__) + " requires at least one: " + str([str(key) for key in self.at_least_one_required]) 
      raise AttributeError(msg) 
     for key, val in iterable.iteritems(): 
      self.__setitem__(key, val) 
     for key, val in kwargs.iteritems(): 
      self.__setitem__(key, val) 

    def update(self, E=None, **F): 
     for key, val in E.iteritems(): 
      self.__setitem__(key, val) 
     for key, val in F.iteritems(): 
      self.__setitem__(key, val) 
     super(StrictDict, self).update({}) 

    def __setitem__(self, key, value): 
     all_allowed = self.allowed.union(self.required).union(self.at_least_one_required).union(self.cannot_coexist) 
     if key not in list(all_allowed): 
      msg = str(self.__class__.__name__) + " does not allow member '" + key + "'" 
      raise AttributeError(msg) 
     if key in list(self.cannot_coexist): 
      for item in list(self.cannot_coexist): 
       if key != item and item in self.keys(): 
        msg = str(self.__class__.__name__) + "does not allow members '" + key + "' and '" + item + "' to coexist'" 
        raise AttributeError(msg) 
     super(StrictDict, self).__setitem__(key, value) 

उदाहरण उपयोग:

class JSONDoc(StrictDict): 
    """ 
    Class corresponding to JSON API top-level document structure 
    http://jsonapi.org/format/#document-top-level 
    """ 
    at_least_one_required={'data', 'errors', 'meta'} 
    allowed={"jsonapi", "links", "included"} 
    cannot_coexist={"data", "errors"} 
    def __setitem__(self, key, value): 
     if key == "included" and "data" not in self.keys(): 
      msg = str(self.__class__.__name__) + " does not allow 'included' member if 'data' member is not present" 
      raise AttributeError(msg) 
     super(JSONDoc, self).__setitem__(key, value) 

json_doc = JSONDoc(
    data={ 
     "id": 5, 
     "type": "movies" 
    }, 
    links={ 
     "self": "http://url.com" 
    } 
) 
1

मैं गुण अधिक https://stackoverflow.com/a/11637457/1766716

  • दोहराएं की मदद कि नहीं है के साथ एक बहुत ही सरल todict विधि कार्यान्वित साथ __
  • हटा तरीकों
  • शुरू होता है
  • (मेरे मामले के लिए, sqlalcemy से आ रही) मैन्युअल रूप से कुछ गुण को हटा दें जो आवश्यक नहीं है

और getattr इस्तेमाल किया शब्दकोश बनाने के लिए।

class User(Base): 
    id = Column(Integer, primary_key=True) 
    firstname = Column(String(50)) 
    lastname = Column(String(50)) 
    password = Column(String(20)) 
    def props(self): 
     return filter(
      lambda a: 
      not a.startswith('__') 
      and a not in ['_decl_class_registry', '_sa_instance_state', '_sa_class_manager', 'metadata'] 
      and not callable(getattr(self, a)), 
      dir(self)) 
    def todict(self): 
     return {k: self.__getattribute__(k) for k in self.props()} 
संबंधित मुद्दे