এটি বেশ জটিল, যেহেতু namedtuple()একটি কারখানা যা থেকে প্রাপ্ত নতুন ধরণের ফিরে আসে tuple। একটি পদ্ধতির ক্ষেত্রে আপনার শ্রেণিটি উত্তরাধিকার সূত্রে প্রাপ্ত হওয়াও হবে UserDict.DictMixinতবে tuple.__getitem__এটি ইতিমধ্যে সংজ্ঞায়িত হয়েছে এবং এটির বৈশিষ্ট্যের নাম নয় বরং কোনও সংখ্যার উপাদানটির অবস্থান নির্দেশ করে বলে প্রত্যাশা করে:
>>> f = foobar('a', 1)
>>> f[0]
'a'
এর হৃদয়ে নেডটুপলটি জেএসএনের জন্য একটি স্বতন্ত্র ফিট, যেহেতু এটি সত্যিই একটি কাস্টম-বিল্ট টাইপ যার মূল নামগুলি টাইপ সংজ্ঞার অংশ হিসাবে স্থির করা হয়েছে , যেখানে অভিধানের মধ্যে মূল নামগুলি সংরক্ষণ করা হয় এমন একটি অভিধানের মত নয়। এটি আপনাকে একটি নেমডটুপলকে "রাউন্ড-ট্রিপিং" বাধা দেয়, যেমন আপনি ডিকের মধ্যে অ্যাপ্লিকেশন নির্দিষ্ট ধরণের মার্কার মতো কোনও ডিকশনারিকে কোনও নামটুপলে আবার ডিকোড করতে পারবেন না {'a': 1, '#_type': 'foobar'}যা কিছুটা হ্যাকি।
এটি আদর্শ নয়, তবে আপনার যদি কেবল অভিধানগুলিতে নেমটুপলগুলি এনকোড করা দরকার , তবে অন্য পদ্ধতিটি হল আপনার জেএসএন এনকোডারকে এই ধরণের বিশেষ ক্ষেত্রে প্রসারিত বা সংশোধন করতে। পাইথন সাবক্লাসিংয়ের উদাহরণ এখানে 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"}}