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"}}