এটি বেশ জটিল, যেহেতু 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"}}