SORU
22 Kasım 2011, Salı


Python ayarlar json seri hale getirilebilir değil

Yineleme yok toplama dahil emin olmak için __hash__ __eq__ yöntemleri ile nesneleri içeren bir python set var.

Bu json sonuç kümesini kodlamak istiyorum ama json.dumps yöntemi için bile boş geçen bir İlişkilendirilmiş yükseltir

    File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o)   " is not JSON serializable")
TypeError: set([]) is not JSON serializable

Json uzantısı oluşturmak biliyorum.JSONEncoder sınıf default özel bir yöntemi var, fakat buna rağmen sete dönüştürme üzerinde nereden başlayacağımdan emin değilim. Varsayılan yöntem içinde yer değerleri bir sözlük oluşturmak ve kodlama iade etmeli miyim? İdeal olarak, ben yapmak istiyorum varsayılan yöntem yapabiliyor tüm veri türleri orijinal kodlayıcı bobinleri (kullanıyorum Mongo gibi bir veri kaynağı, tarih gibi zam bu hata çok)

Doğru yönde herhangi bir ipucu mutluluk duyacağız.

DÜZENLEME:

Cevap için teşekkürler! Belki de daha hassas olmalıydım.

(Ve upvoted) cevaplarını burada kümesi tercüme sınırlamaları etrafında almak için kullanılan, ama onların da bir sorunu iç anahtarları.

Küme nesneleri __dict__, çevirmek karmaşık nesnelerdir ama kendileri de json kodlayıcı temel türleri için uygun olabilecek özellikleri için değerleri içerebilir.

Çok farklı geliyor bu set, ve karma temelde hesaplar bir benzersiz kimlik için bir varlık, ama gerçek ruh NoSQL söyleyecek bir şey yok tam olarak ne çocuk nesne içerir.

Nesne için bir tarih değeri içeriyor olabilir başka bir anahtar içeren başka bir şema var ise starts içeren "non-prmitive" nesneler.

Bu yüzden tek çözüm aklıma edildi genişletmek JSONEncoder değiştirmek için default yöntem açmak için farklı durumlar - ama emin değilim nasıl bu ve belgelendirme muğlak. İç içe nesneleri, varsayılan değer dönen anahtar ile gitmek, ya da sadece genel bir amaç bakar/iptal bulunur mu? Nasıl bu yöntem iç içe geçmiş değerler uyması mu? Önceki sorulara baktım ve davanın özel kodlama (ne yazık ki görünüyor ki burada yapmak istiyorum ne gibi.) için en iyi yaklaşım bulmak için görünmüyor olabilir ettik

Ben yardım için teşekkür ederiz!

CEVAP
22 Kasım 2011, Salı


JSON gösterim var sadece bir avuç yerli türleri (nesneler, diziler, dizeleri, sayı, Boolean ve null), bu yüzden hiçbir şey seri olarak JSON gerekiyor ifade edildiği gibi bu tür.

json module docs görüldüğü gibi bu dönüşüm otomatik olarak yapılabilirJSONEncoderveJSONDecoderama sonra olur PES başka bir yapı gerekebilir (eğer ayarlar dönüştürmek için bir liste, o zaman kaybedersiniz yeteneğini kurtarmak düzenli listeler; dönüştürme setleri için bir sözlük kullanarak dict.fromkeys(s) seni kaybetmek yeteneğini kurtarmak sözlük).

Daha sofistike bir çözüm oluşturmak-diğer yerel JSON tipleri ile birlikte, özel bir türü. Bu listeler, kümeler, dicts, ondalık sayı, datetime nesneleri içeren iç içe geçmiş yapıları, vb. kaydedebilirsiniz:

from json import dumps, loads, JSONEncoder, JSONDecoder
import pickle

class PythonObjectEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (list, dict, str, unicode, int, float, bool, type(None))):
            return JSONEncoder.default(self, obj)
        return {'_python_object': pickle.dumps(obj)}

def as_python_object(dct):
    if '_python_object' in dct:
        return pickle.loads(str(dct['_python_object']))
    return dct

İşte örnek bir oturum listeleri, dicts ve ayarlar işleyebilir gösteren:

>>> data = [1,2,3, set(['knights', 'who', 'say', 'ni']), {'key':'value'}, Decimal('3.14')]

>>> j = dumps(data, cls=PythonObjectEncoder)

>>> loads(j, object_hook=as_python_object)
[1, 2, 3, set(['knights', 'say', 'who', 'ni']), {u'key': u'value'}, Decimal('3.14')]

Alternatif olarak, YAML, Twisted Jelly veya Python gibi serileştirme tekniği pickle module daha genel amaçlı kullanım için yararlı olabilir. Bu veri çok daha geniş bir yelpazede destek.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Adam Khoury

    Adam Khoury

    23 Ocak 2008
  • AlaskanGrizzly

    AlaskanGrizz

    30 EKİM 2009
  • Kamikazeepanda

    Kamikazeepan

    5 ŞUBAT 2006