यह बहुत मुश्किल है, क्योंकि namedtuple()एक कारखाना है जो एक नए प्रकार से प्राप्त होता है tuple। एक दृष्टिकोण यह होगा कि आपकी कक्षा भी विरासत में मिली हो UserDict.DictMixin, लेकिन tuple.__getitem__पहले से ही एक पूर्णांक को परिभाषित करता है और यह अपेक्षा करता है कि तत्व की स्थिति को निरूपित किया जाए, न कि इसकी विशेषता का नाम:
>>> f = foobar('a', 1)
>>> f[0]
'a'
इसके दिल में नामित नाम JSON के लिए एक विषम फिट है, क्योंकि यह वास्तव में एक कस्टम-निर्मित प्रकार है जिसके प्रमुख नाम टाइप परिभाषा के हिस्से के रूप में तय किए गए हैं , एक शब्दकोश के विपरीत जहां प्रमुख नाम उदाहरण के अंदर संग्रहीत होते हैं। यह आपको नामांकित नाम के "राउंड-ट्रिपिंग" से रोकता है, उदाहरण के लिए, आप डिक्शनरी में किसी अन्य जानकारी के बिना किसी नाम-पत्र में वापस शब्दकोश में डिकोड नहीं कर सकते हैं, जैसे कि एक ऐप-विशिष्ट प्रकार का मार्कर {'a': 1, '#_type': 'foobar'}, जो कि थोड़ा सा हैकी है।
यह आदर्श नहीं है, लेकिन अगर आपको केवल नामांकितों को शब्दकोशों में सांकेतिक शब्दों में बदलना चाहिए , तो एक अन्य दृष्टिकोण इन प्रकारों को विशेष मामले में अपने JSON एनकोडर को विस्तारित या संशोधित करना है। यहाँ पायथन को उपवर्गित करने का एक उदाहरण दिया गया है json.JSONEncoder। यह सुनिश्चित करने की समस्या से निपटा जाता है कि नेस्टेड नल्टल्स को ठीक से शब्दकोशों में बदल दिया गया है:
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"}}