Bu oldukça zordur, çünkü namedtuple()
türetilmiş yeni bir türü döndüren bir fabrika tuple
. Bir yaklaşım, sınıfınızın da miras almasını sağlamak olabilir UserDict.DictMixin
, ancak tuple.__getitem__
zaten tanımlanmıştır ve özelliğinin adını değil, öğenin konumunu belirten bir tam sayı beklemektedir:
>>> f = foobar('a', 1)
>>> f[0]
'a'
Adlandırılmış tup, temelde JSON için garip bir uyumdur, çünkü anahtar adlarının örnek içinde depolandığı bir sözlüğün aksine, anahtar adları tür tanımının bir parçası olarak sabitlenen özel olarak oluşturulmuş bir türdür . Bu, adlandırılmış bir grubu "geri döndürmenizi" engeller, örneğin, bir sözlüğün kodunu başka bir bilgi parçası olmadan adlandırılmış bir gruba geri çözemezsiniz {'a': 1, '#_type': 'foobar'}
.
Bu ideal değildir, ancak yalnızca adlandırılmış çiftleri sözlüklere kodlamanız gerekiyorsa , başka bir yaklaşım da JSON kodlayıcınızı bu türlere özel duruma göre genişletmek veya değiştirmektir. İşte Python'un alt sınıflamasına bir örnek json.JSONEncoder
. Bu, yuvalanmış adlandırılmış tabloların doğru şekilde sözlüğe dönüştürülmesini sağlama sorununu çözer:
from collections import namedtuple
from json import JSONEncoder
class MyEncoder(JSONEncoder):
def _iterencode(self, obj, markers=None):
if isinstance(obj, tuple) and hasattr(obj, '_asdict'):
gen = self._iterencode_dict(obj._asdict(), markers)
else:
gen = JSONEncoder._iterencode(self, obj, markers)
for chunk in gen:
yield chunk
class foobar(namedtuple('f', 'foo, bar')):
pass
enc = MyEncoder()
for obj in (foobar('a', 1), ('a', 1), {'outer': foobar('x', 'y')}):
print enc.encode(obj)
{"foo": "a", "bar": 1}
["a", 1]
{"outer": {"foo": "x", "bar": "y"}}