নেস্টেড পাইথন ডিককে আপত্তি জানাতে রূপান্তর করবেন?


537

আমি কিছু নেস্টেড ডিক্টস এবং লিস্টগুলি (অর্থাত্ জাভাস্ক্রিপ্ট-স্টাইলে অবজেক্ট সিনট্যাক্স) দিয়ে ডিকের উপর অ্যাট্রিবিউট অ্যাক্সেস ব্যবহার করে ডেটা পাওয়ার একটি দুর্দান্ত উপায় সন্ধান করছি।

উদাহরণ স্বরূপ:

>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}

এইভাবে অ্যাক্সেসযোগ্য হওয়া উচিত:

>>> x = dict2obj(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
bar

আমি মনে করি, পুনরাবৃত্তি ছাড়া এটি সম্ভব নয়, তবে ডিক্টসের জন্য কোনও অবজেক্ট স্টাইল পাওয়ার একটি দুর্দান্ত উপায় কী হবে?


6
আমি সম্প্রতি অনুরূপ কিছু করার চেষ্টা করছিলাম, তবে একটি পুনরাবৃত্ত অভিধান কী ("থেকে" - যা পাইথন কীওয়ার্ড) আমাকে এটির মধ্য দিয়ে যেতে বাধা দেয়। কারণ এই বৈশিষ্ট্যটি অ্যাক্সেস করতে আপনি "x.from" ব্যবহার করার সাথে সাথেই আপনি একটি সিনট্যাক্স ত্রুটি পেয়ে যাবেন।
ডাবি স্ট্রাউস

3
এটি আসলেই একটি সমস্যা, তবে আমি বড় "ডিক কনস্ট্রাক্টসগুলিতে অ্যাক্সেসে জীবনকে সহজ করার জন্য" "থেকে" এড়িয়ে যেতে পারি :) x ['a'] ['ডি'] [1] ['ফু'] টাইপ করা সত্যিই বিরক্তিকর, তাই xad [1] .ফু বিধি। আপনার যদি প্রয়োজন হয় তবে আপনি এটি getattr (x, 'from') এর মাধ্যমে অ্যাক্সেস করতে পারেন বা এর পরিবর্তে অ্যাট্রিবিউট হিসাবে _ ব্যবহার করতে পারেন।
মার্ক

5
from_বরং পিইপি 8_from অনুযায়ী ।
কোস

1
আপনি getattr(x, 'from')বৈশিষ্ট্যটির নাম পরিবর্তনের পরিবর্তে ব্যবহার করতে পারেন ।
জর্জ ভি। রিলি

3
এই "সমাধানগুলি" বেশিরভাগ কাজ করে বলে মনে হয় না (এমনকি স্বীকৃত একওd1.b.c , বাসা বাঁধার অনুমতি দেয় না ), আমি মনে করি এটি স্পষ্টভাবে আপনার কোনও লাইব্রেরি থেকে কিছু ব্যবহার করা উচিত, যেমন সংগ্রহ থেকে নেমটুপল , যেমন এই উত্তরটি জানিয়েছে , .. ।
অ্যান্ডি হেডেন

উত্তর:


659

আপডেট: পাইথন ২.6 এবং তারপরে, namedtupleডেটা স্ট্রাকচারটি আপনার প্রয়োজনীয়তার জন্য উপযুক্ত কিনা তা বিবেচনা করুন:

>>> from collections import namedtuple
>>> MyStruct = namedtuple('MyStruct', 'a b d')
>>> s = MyStruct(a=1, b={'c': 2}, d=['hi'])
>>> s
MyStruct(a=1, b={'c': 2}, d=['hi'])
>>> s.a
1
>>> s.b
{'c': 2}
>>> s.c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyStruct' object has no attribute 'c'
>>> s.d
['hi']

বিকল্প (মূল উত্তরের বিষয়বস্তু) হ'ল:

class Struct:
    def __init__(self, **entries):
        self.__dict__.update(entries)

তারপরে, আপনি ব্যবহার করতে পারেন:

>>> args = {'a': 1, 'b': 2}
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s.a
1
>>> s.b
2

19
এখানে একই - এটি মঙ্গোডিবি এর মতো নথিভিত্তিক ডাটাবেসগুলি থেকে পাইথন অবজেক্টগুলিকে পুনর্গঠনের জন্য বিশেষভাবে কার্যকর।
মাইকম্যাকানা

13
প্রিন্টিয়ার মুদ্রণের জন্য অ্যাড: ডিএফ রেপ্রাই __ (স্ব): ফিরে '<% s>'% স্ট্র ('\ n' .জয়েন ('% s:% s'% (কে, রিপ্রি (ভি)) এর জন্য (কে, ভি ) স্বতঃআর .__ ডিক্টর .iteitems ())
ছয়টি

15
এটি কি নেস্টেড ডিকশনারি দিয়ে কাজ করবে? এবং বস্তু এবং তালিকা ইত্যাদি সহ ডিক্টসগুলি কি কোনও ক্যাচ আছে?
স্যাম স্টোলেঙ্গা

5
@ সাম এস: এটি Structনেস্টেড অভিধান থেকে নেস্টেড এস তৈরি করবে না , তবে সাধারণভাবে মানটির ধরণটি যে কোনও কিছু হতে পারে। কী অবজেক্ট স্লটের উপযুক্ত হওয়ার জন্য সীমাবদ্ধ
এলি বেন্ডারস্কি

51
-১ কারণ ক) এটি নেস্টেড ডিসটিকসগুলির জন্য কাজ করে না, যা প্রশ্নটি পরিষ্কারভাবে জিজ্ঞাসা করেছিল এবং খ) মানক লাইব্রেরিতে বর্তমানে একই কার্যকারিতা বিদ্যমান রয়েছে argparse.Namespace (যা এটিও সংজ্ঞায়িত করেছে__eq__ , __ne__, __contains__)।
wim

110
class obj(object):
    def __init__(self, d):
        for a, b in d.items():
            if isinstance(b, (list, tuple)):
               setattr(self, a, [obj(x) if isinstance(x, dict) else x for x in b])
            else:
               setattr(self, a, obj(b) if isinstance(b, dict) else b)

>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> x = obj(d)
>>> x.b.c
2
>>> x.d[1].foo
'bar'

7
ভাল! যদিও আমি ছোট মেমরির পদক্ষেপের জন্য .items () দ্বারা .iteitems () প্রতিস্থাপন করব।
এরিক হে লেবিগোট

7
যদি কোনও ওপি প্রয়োজনীয়তা না হয় তবে এটি কোনও সমস্যা নয় - তবে মনে রাখবেন যে এটি তালিকার মধ্যে তালিকাগুলিতে পুনরাবৃত্তভাবে প্রক্রিয়া করবে না।
আনন

3
আমি বুঝতে পারি এটি একটি পুরানো উত্তর, তবে এই দিনগুলিতে সেই কুৎসিত লাইনের পরিবর্তে একটি বিমূর্ত বেস ক্লাস ব্যবহার করা ভাল হবেif isinstance(b, (list, tuple)):
উইম

4
টিপ: পাঠযোগ্য স্ট্রিং উপস্থাপনার মতো অতিরিক্ত বৈশিষ্ট্যগুলির জন্য objবর্গকে উত্তরাধিকার argparse.Namespaceসূচনা করুন।
সেরানানো

2
ব্যবহারের ক্ষেত্রে উপর নির্ভর করে, সাধারণত আমরা চেক করবে এটা না একটি স্ট্রিং টাইপ কিন্তু এটা যে হয় একটি ক্রম টাইপ
Wim

107

আশ্চর্যজনকভাবে কেউ গুচ্ছের কথা উল্লেখ করেনি । এই গ্রন্থাগারটি একচেটিয়াভাবে ডিক অবজেক্টগুলিতে অ্যাট্রিবিউট স্টাইল অ্যাক্সেস সরবরাহ করতে বোঝানো হয়েছে এবং ওপি যা চায় ঠিক তা করে। একটি প্রদর্শন:

>>> from bunch import bunchify
>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> x = bunchify(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
'bar'

পাইথন 3 গ্রন্থাগারটি https://github.com/Infinidat/munch এ উপলব্ধ - ক্রেডিট কোডিজুতে যায়


16
এবং সেখানে একটি অজগর 3 সামঞ্জস্যপূর্ণ (2.6-3.4 প্রদর্শিত হবে) মঞ্চ নামে গুচ্ছের শাখা রয়েছে: github.com/Infinidat/munch
codzu

গুচ্ছ এগুলির সর্বোত্তম সমাধান কারণ এটি একাধিক ধরণের সিরিয়ালাইজেশন ভালভাবে সমর্থন করে, এবং বজায় থাকে। দুর্দান্ত, আপনাকে ধন্যবাদ। আমি আশা করি পাইথন 3 সংস্করণটির নাম একই জিনিস রাখা হয়েছে, কারণ কেন নয়।
জোনাথন

4
সুতরাং এই বিষয়টির জন্য কেবল একটি পূর্বসূচী, গুচ্ছ এবং আকর্ষণীয়তা খুব ধীর। তারা যখন আমাদের অ্যাপ্লিকেশনটিতে ঘন ঘন ব্যবহার দেখেছিল তখন তারা যথাক্রমে আমার অনুরোধের প্রায় 1/3 এবং 1/2 গ্রাস গ্রহণ করেছিল। অবশ্যই উপেক্ষা করার মতো কিছু নয়। এটি সম্পর্কে আরও কথা বলুন stackoverflow.com/a/31569634/364604
JayD3e

যদিও এটি ডিক্টগুলিতে অবজেক্টের মতো অ্যাক্সেসের অনুমতি দেয় না, এটি গ্যাটট্রারের মাধ্যমে এটি করে । এটি আইপিথনের মতো স্মার্ট আরএপিএলগুলিতে অন্তর্মুখিটিকে কঠিন করে তোলে।
জিডর্ন

কৌতূহল কীভাবে এটি JSONpath github.com/kennknowles/python-jsonpath-rw এর
মার্কহু

64
x = type('new_dict', (object,), d)

তারপরে এতে পুনরাবৃত্তি যুক্ত করুন এবং আপনার কাজ শেষ।

সম্পাদন করা কিভাবে এই আমি এটা বাস্তবায়ন চাই হল:

>>> d
{'a': 1, 'b': {'c': 2}, 'd': ['hi', {'foo': 'bar'}]}
>>> def obj_dic(d):
    top = type('new', (object,), d)
    seqs = tuple, list, set, frozenset
    for i, j in d.items():
        if isinstance(j, dict):
            setattr(top, i, obj_dic(j))
        elif isinstance(j, seqs):
            setattr(top, i, 
                type(j)(obj_dic(sj) if isinstance(sj, dict) else sj for sj in j))
        else:
            setattr(top, i, j)
    return top

>>> x = obj_dic(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
'bar'

1
আপনি কেন টাইপ-অবজেক্ট তৈরি করছেন এবং তা তাত্ক্ষণিকভাবে তৈরি করছেন না? এটা কি আরও যৌক্তিক হবে না? মানে, top_instance = top()আপনি যেখানে ফিরে আসবেন না কেন সেখানে ফিরে যাবেন না top?
প্যানকেকে

6
"পাতাগুলি" ডেটাটির জন্য দুর্দান্ত, তবে উদাহরণগুলি সুবিধার্থে " xx.b<class '__main__.new'>
ডুমুর

46

সেখানে একটি সংগ্রাহক সহায়ক বলা হয়েছে namedtuple, এটি আপনার পক্ষে এটি করতে পারে:

from collections import namedtuple

d_named = namedtuple('Struct', d.keys())(*d.values())

In [7]: d_named
Out[7]: Struct(a=1, b={'c': 2}, d=['hi', {'foo': 'bar'}])

In [8]: d_named.a
Out[8]: 1

28
এটি নেস্টেড ডিক্টসের জন্য পুনরাবৃত্তির প্রশ্নের উত্তর দেয় না।
উপভোগযোগ্য

4
আপনি নামকরণকৃতদের পরিবর্তন করতে পারবেন না।
সর্বোচ্চ

আমরা কি গ্যারান্টি দিতে পারি যে তালিকার ক্রমটি কী () এবং মানগুলি () অনুসারে মিলিয়েছে? মানে, এটি যদি অর্ডারডিক্ট হয় তবে হ্যাঁ। তবে স্ট্যান্ডার্ড ডিক্ট? আমি জানি যে সিপিথন 3.6+ এবং পাইপাই "কমপ্যাক্ট" ডিক্টস অর্ডার করা হয়েছে, তবে ডকুমেন্টেশন উদ্ধৃত করে: "এই নতুন বাস্তবায়নের ক্রম-সংরক্ষণের দিকটি একটি বাস্তবায়ন বিশদ হিসাবে বিবেচিত হয় এবং তার উপর নির্ভর করা উচিত নয়"
হাভোক

38
class Struct(object):
    """Comment removed"""
    def __init__(self, data):
        for name, value in data.iteritems():
            setattr(self, name, self._wrap(value))

    def _wrap(self, value):
        if isinstance(value, (tuple, list, set, frozenset)): 
            return type(value)([self._wrap(v) for v in value])
        else:
            return Struct(value) if isinstance(value, dict) else value

যে কোনও গভীরতার যে কোনও সিকোয়েন্স / ডিক / মান কাঠামো সহ ব্যবহার করা যেতে পারে।


4
এই উত্তর হওয়া উচিত। এটি বাসা বাঁধার জন্য ভাল কাজ করে। আপনি এটি json.load () এর জন্য অবজেক্ট_হুক হিসাবেও ব্যবহার করতে পারেন।
010110110101

2
২০০৯ সাল থেকে সাইলেন্টগোস্টের কার্যকরী উত্তরের অনুরূপ - লিফ নোড ডেটা অ্যাক্সেসযোগ্য তবে প্যারেন্ট / টুইগস অবজেক্টের রেফারেন্স হিসাবে প্রদর্শন করে। প্রিন্ট-মুদ্রণ করতে,def __repr__(self): return '{%s}' % str(', '.join("'%s': %s" % (k, repr(v)) for (k, v) in self.__dict__.iteritems()))
MarkHu

5
পাইথন 3.x ব্যবহারকারী: এটা শুধু .items()পরিবর্তে .iteritems()লাইন 4. মধ্যে (ফাংশন নতুন নামকরণ করা হয়, কিন্তু আছে essentialy একই )
আধুনিক পোষ্ট নব্য

নেস্টেড বস্তুর জন্য নিখুঁত কাজ করে, ধন্যবাদ! আমি হিসাবে একটি মন্তব্য newbies হিসাবে, পাইথন 3 iteritems () অবশ্যই আইটেম () এ পরিবর্তন করতে হবে
অস্কার Andreu

31

আমি যা অনুভব করি তা গ্রহণ করা পূর্ববর্তী উদাহরণগুলির সেরা দিক, আমি এখানে যা এলাম তা এখানে:

class Struct:
  '''The recursive class for building and representing objects with.'''
  def __init__(self, obj):
    for k, v in obj.iteritems():
      if isinstance(v, dict):
        setattr(self, k, Struct(v))
      else:
        setattr(self, k, v)
  def __getitem__(self, val):
    return self.__dict__[val]
  def __repr__(self):
    return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for
      (k, v) in self.__dict__.iteritems()))

দ্রষ্টব্য যে নির্মাণকর্তাটি ছোট করা যেতে পারে: def __init__(self, dct): for k, v in dct.iteritems(): setattr(self, k, isinstance(v, dict) and self.__class__(v) or v) যা স্পষ্ট কলটিও সরিয়ে দেয়Struct
জর্জ ভি। রিলি

2
আমি বরং আমার নিজের উত্তরকে কম করে দেবো না, তবে এ দিকে ফিরে তাকিয়ে আমি লক্ষ্য করেছি যে এটি ক্রম ধরণের ক্ষেত্রে পুনরাবৃত্তি হয় না। xd [1] .ফুট এই ক্ষেত্রে ব্যর্থ হয়।
andyvanee

2
isinstance(v, dict)চেক ভাল হিসাবে হবে isinstance(v, collections.Mapping)তাই এটি জিনিষ অভি মত ভবিষ্যৎ সব ব্যবস্থা করতে সক্ষম
hobs

29

যদি আপনার ডিকটি আসছে json.loads(), আপনি এটিকে একটি লাইনে পরিবর্তে (ডিকের পরিবর্তে) কোনও বস্তুতে পরিণত করতে পারেন:

import json
from collections import namedtuple

json.loads(data, object_hook=lambda d: namedtuple('X', d.keys())(*d.values()))

কীভাবে জেএসএন ডেটাটিকে পাইথন অবজেক্টে রূপান্তর করতে হয় তা দেখুন ।


.loadsআপনার কাছে বিশাল জেএসওএন অবজেক্ট থাকলে নিয়মিত তুলনায় অনেক ধীর বলে মনে হচ্ছে
মাইকেলসনোডেন

16

আপনি যদি কোনও জিনিস হিসাবে ডিক কীগুলি অ্যাক্সেস করতে চান (বা কঠিন কীগুলির জন্য ডিক হিসাবে), এটি পুনরাবৃত্তি করুন এবং মূল ডিকটি আপডেট করতে সক্ষম হন, আপনি এটি করতে পারেন:

class Dictate(object):
    """Object view of a dict, updating the passed in dict when values are set
    or deleted. "Dictate" the contents of a dict...: """

    def __init__(self, d):
        # since __setattr__ is overridden, self.__dict = d doesn't work
        object.__setattr__(self, '_Dictate__dict', d)

    # Dictionary-like access / updates
    def __getitem__(self, name):
        value = self.__dict[name]
        if isinstance(value, dict):  # recursively view sub-dicts as objects
            value = Dictate(value)
        return value

    def __setitem__(self, name, value):
        self.__dict[name] = value
    def __delitem__(self, name):
        del self.__dict[name]

    # Object-like access / updates
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        self[name] = value
    def __delattr__(self, name):
        del self[name]

    def __repr__(self):
        return "%s(%r)" % (type(self).__name__, self.__dict)
    def __str__(self):
        return str(self.__dict)

ব্যবহারের উদাহরণ:

d = {'a': 'b', 1: 2}
dd = Dictate(d)
assert dd.a == 'b'  # Access like an object
assert dd[1] == 2  # Access like a dict
# Updates affect d
dd.c = 'd'
assert d['c'] == 'd'
del dd.a
del dd[1]
# Inner dicts are mapped
dd.e = {}
dd.e.f = 'g'
assert dd['e'].f == 'g'
assert d == {'c': 'd', 'e': {'f': 'g'}}

13
>>> def dict2obj(d):
        if isinstance(d, list):
            d = [dict2obj(x) for x in d]
        if not isinstance(d, dict):
            return d
        class C(object):
            pass
        o = C()
        for k in d:
            o.__dict__[k] = dict2obj(d[k])
        return o


>>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
>>> x = dict2obj(d)
>>> x.a
1
>>> x.b.c
2
>>> x.d[1].foo
'bar'

12

আমি অ্যাট্রিক্ট এবং এর দুটি চেষ্টা করেই শেষ করেছি গুচ্ছলাইব্রেরিগুলি এবং সেগুলি আমার ব্যবহারগুলির জন্য খুব ধীর হয়ে গেছে। একটি বন্ধু এবং আমি এটি সন্ধানের পরে, আমরা দেখতে পেলাম যে এই লাইব্রেরিগুলি লেখার মূল পদ্ধতিটি গ্রন্থাগারের ফলে আগ্রাসীভাবে একটি নেস্টেড বস্তুর মাধ্যমে পুনরাবৃত্তি করে এবং অভিধানের সামগ্রীর অনুলিপিগুলি তৈরি করে। এটি মাথায় রেখে আমরা দুটি মূল পরিবর্তন করেছি। 1) আমরা অলস-বোঝা বৈশিষ্ট্য তৈরি করেছি 2) অভিধানের কোনও বস্তুর অনুলিপি তৈরির পরিবর্তে, আমরা একটি হালকা ওজনের প্রক্সি অবজেক্টের অনুলিপি তৈরি করি। এটিই চূড়ান্ত বাস্তবায়ন। এই কোডটি ব্যবহারের পারফরম্যান্স বৃদ্ধি অবিশ্বাস্য। অ্যাট্রিক্টিক্ট বা গুচ্ছ ব্যবহার করার সময়, এই দুটি গ্রন্থাগার একা আমার অনুরোধের সময়ের (কি !?) যথাক্রমে যথাক্রমে 1/2 এবং 1/3 গ্রাস করেছিল? এই কোডটি সেই সময়টিকে প্রায় কিছুতেই কমিয়ে দেয় না (কোথাও 0.5 মিলিমিটারের পরিসর) to এটি অবশ্যই আপনার প্রয়োজনের উপর নির্ভর করে,

class DictProxy(object):
    def __init__(self, obj):
        self.obj = obj

    def __getitem__(self, key):
        return wrap(self.obj[key])

    def __getattr__(self, key):
        try:
            return wrap(getattr(self.obj, key))
        except AttributeError:
            try:
                return self[key]
            except KeyError:
                raise AttributeError(key)

    # you probably also want to proxy important list properties along like
    # items(), iteritems() and __len__

class ListProxy(object):
    def __init__(self, obj):
        self.obj = obj

    def __getitem__(self, key):
        return wrap(self.obj[key])

    # you probably also want to proxy important list properties along like
    # __iter__ and __len__

def wrap(value):
    if isinstance(value, dict):
        return DictProxy(value)
    if isinstance(value, (tuple, list)):
        return ListProxy(value)
    return value

আসল বাস্তবায়নটি এখানে https://stackoverflow.com/users/704327/michael-merickel দ্বারা দেখুন ।

অন্যটি লক্ষণীয় বিষয়, এই বাস্তবায়নটি বেশ সহজ এবং আপনার প্রয়োজন সমস্ত পদ্ধতি কার্যকর করে না। ডিক্ট প্রক্সি বা লিস্টপ্রক্সী অবজেক্টে যেমন প্রয়োজন তেমন আপনাকে লিখতে হবে।


9

x.__dict__.update(d) জরিমানা করা উচিত।


আপনার উত্তরের জন্য ধন্যবাদ, তবে এক্স কি? ডিক বা একটি স্ট্যান্ডার্ড অবজেক্ট? আপনি আমাকে একটি ইঙ্গিত দিতে পারেন দয়া করে
মার্ক

এক্স আপনার অবজেক্ট। প্রতিটি বস্তুর একটি ডিক থাকে । আপডেট করার মাধ্যমে অভি আপনি আসলে আপডেট করছি একটি অবজেক্টকে চাবি এতে Vars।
অ্যালেক্স রডরিগস

সাহসী শব্দগুলি হ'ল _ _ ডিক _ _
অ্যালেক্স রডরিগস

15
এটি নেস্টেড অভিধানগুলি পরিচালনা করবে না।
ফোগলবার্ড

প্রতিটি বস্তুর একটি থাকে না __dict__: চেষ্টা করুন object().__dict__এবং আপনি পাবেনAttributeError: 'object' object has no attribute '__dict__'
উইল ম্যানলে

8

আপনি একটি কাস্টম অবজেক্ট হুক দিয়ে স্ট্যান্ডার্ড লাইব্রেরির jsonমডিউলটি উত্তোলন করতে পারেন :

import json

class obj(object):
    def __init__(self, dict_):
        self.__dict__.update(dict_)

def dict2obj(d):
    return json.loads(json.dumps(d), object_hook=obj)

ব্যবহারের উদাহরণ:

>>> d = {'a': 1, 'b': {'c': 2}, 'd': ['hi', {'foo': 'bar'}]}
>>> o = dict2obj(d)
>>> o.a
1
>>> o.b.c
2
>>> o.d[0]
u'hi'
>>> o.d[1].foo
u'bar'

এবং এটি কেবল কঠোরভাবে পঠনযোগ্য নয় যেমন এটি রয়েছে namedtuple, যেমন আপনি মান পরিবর্তন করতে পারেন - কাঠামো নয়:

>>> o.b.c = 3
>>> o.b.c
3

1
এতদূর সেরা উত্তর
কনার

নেস্টেড উপাদানগুলির জন্য json লোডিং প্রক্রিয়াটি ব্যবহার করার ধারণাটি আমার পছন্দ হয়। তবে আমাদের ইতিমধ্যে একটি ডিক রয়েছে এবং আমি এটি পছন্দ করি না যে এটির একটি বস্তুতে মানচিত্র তৈরি করার জন্য কারও কাছে একটি স্ট্রিং তৈরি করা দরকার needs আমি বরং এমন একটি সমাধান চাই যা ডিক থেকে সরাসরি বস্তু তৈরি করে।
সান্দ্রো

1
চাহিদা স্ট্রিং রূপান্তর প্রথম কিন্তু প্রশংসনীয় জেনেরিক এক হিসাবে মাধ্যমে এটি প্রসারিত করতে পারে json.JSONEncoderএবং object_hook
সান্দ্রো

6

এটি আপনার শুরু করা উচিত:

class dict2obj(object):
    def __init__(self, d):
        self.__dict__['d'] = d

    def __getattr__(self, key):
        value = self.__dict__['d'][key]
        if type(value) == type({}):
            return dict2obj(value)

        return value

d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}

x = dict2obj(d)
print x.a
print x.b.c
print x.d[1].foo

এটি তালিকার জন্য এখনও কাজ করে না। ডিকটস মোড়ানোর জন্য আপনাকে তালিকাগুলি একটি ব্যবহারকারীর তালিকাতে এবং ওভারলোড __getitem__করতে হবে।


2
এটি তালিকাগুলির জন্য কাজ করতে, এর উত্তর if isinstance(d, list)থেকে ধারাটি ব্যবহার করুন Anon
বিনয় সাজিপ

6

আমি জানি ইতিমধ্যে এখানে ইতিমধ্যে প্রচুর উত্তর রয়েছে এবং আমি পার্টিতে দেরী করেছি তবে এই পদ্ধতিটি পুনরাবৃত্তভাবে এবং 'জায়গায়' একটি অভিধানকে একটি বস্তুর মতো কাঠামোতে রূপান্তরিত করবে ... 3.xx এ কাজ করে

def dictToObject(d):
    for k,v in d.items():
        if isinstance(v, dict):
            d[k] = dictToObject(v)
    return namedtuple('object', d.keys())(*d.values())

# Dictionary created from JSON file
d = {
    'primaryKey': 'id', 
    'metadata': 
        {
            'rows': 0, 
            'lastID': 0
        }, 
    'columns': 
        {
            'col2': {
                'dataType': 'string', 
                'name': 'addressLine1'
            }, 
            'col1': {
                'datatype': 'string', 
                'name': 'postcode'
            }, 
            'col3': {
                'dataType': 'string', 
                'name': 'addressLine2'
            }, 
            'col0': {
                'datatype': 'integer', 
                'name': 'id'
            }, 
            'col4': {
                'dataType': 'string', 
                'name': 'contactNumber'
            }
        }, 
        'secondaryKeys': {}
}

d1 = dictToObject(d)
d1.columns.col1 # == object(datatype='string', name='postcode')
d1.metadata.rows # == 0

"অবজেক্টের মতো কাঠামো" বলতে কী বোঝ?
মোরালকোড

1
হাঁসের টাইপিং নীতিটির কারণে অবজেক্টের মতো। আমার অর্থ হ'ল আপনি এর বৈশিষ্ট্যগুলি অ্যাক্সেস করতে পারবেন আপনার মতো যদি এটি কোনও শ্রেণীর উদাহরণ হয়। তবে এটি সেই অর্থে কোনও বস্তু নয়, এটি একটি নামকৃত টিপল।
আইডন হ্যাডন-রাইট


4

কিছু সময় আগে আমি প্রায় একটি ব্যবহার করেছি এমন একটি সমাধান আমাকে ব্যাখ্যা করুন । তবে প্রথমে, আমি না করার কারণটি নীচের কোডটি দ্বারা চিত্রিত হয়েছে:

d = {'from': 1}
x = dict2obj(d)

print x.from

এই ত্রুটি দেয়:

  File "test.py", line 20
    print x.from == 1
                ^
SyntaxError: invalid syntax

কারণ "থেকে" একটি পাইথন কীওয়ার্ড রয়েছে এমন নির্দিষ্ট অভিধান কী রয়েছে যা আপনি অনুমতি দিতে পারবেন না।


এখন আমার সমাধান অভিধানের আইটেমগুলিতে সরাসরি তাদের নাম ব্যবহার করে অ্যাক্সেসের অনুমতি দেয়। তবে এটি আপনাকে "অভিধান শব্দার্থক" ব্যবহার করার অনুমতি দেয় allows উদাহরণ ব্যবহারের সাথে কোডটি এখানে:

class dict2obj(dict):
    def __init__(self, dict_):
        super(dict2obj, self).__init__(dict_)
        for key in self:
            item = self[key]
            if isinstance(item, list):
                for idx, it in enumerate(item):
                    if isinstance(it, dict):
                        item[idx] = dict2obj(it)
            elif isinstance(item, dict):
                self[key] = dict2obj(item)

    def __getattr__(self, key):
        return self[key]

d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}

x = dict2obj(d)

assert x.a == x['a'] == 1
assert x.b.c == x['b']['c'] == 2
assert x.d[1].foo == x['d'][1]['foo'] == "bar"

1
শ্রেণি কাঠামো: ডিফ থিম __ (স্ব, ** এন্ট্রি): স্ব .__ ডিক .আপডেট (এন্ট্রি)
কেনেথ রেইটজ

4

পুরানো প্রশ্নোত্তর, তবে আমি আরও কিছু কথা বলি। রিকার্সিভ ডিক সম্পর্কে কেউ কথা বলে মনে হচ্ছে না। এটি আমার কোড:

#!/usr/bin/env python

class Object( dict ):
    def __init__( self, data = None ):
        super( Object, self ).__init__()
        if data:
            self.__update( data, {} )

    def __update( self, data, did ):
        dataid = id(data)
        did[ dataid ] = self

        for k in data:
            dkid = id(data[k])
            if did.has_key(dkid):
                self[k] = did[dkid]
            elif isinstance( data[k], Object ):
                self[k] = data[k]
            elif isinstance( data[k], dict ):
                obj = Object()
                obj.__update( data[k], did )
                self[k] = obj
                obj = None
            else:
                self[k] = data[k]

    def __getattr__( self, key ):
        return self.get( key, None )

    def __setattr__( self, key, value ):
        if isinstance(value,dict):
            self[key] = Object( value )
        else:
            self[key] = value

    def update( self, *args ):
        for obj in args:
            for k in obj:
                if isinstance(obj[k],dict):
                    self[k] = Object( obj[k] )
                else:
                    self[k] = obj[k]
        return self

    def merge( self, *args ):
        for obj in args:
            for k in obj:
                if self.has_key(k):
                    if isinstance(self[k],list) and isinstance(obj[k],list):
                        self[k] += obj[k]
                    elif isinstance(self[k],list):
                        self[k].append( obj[k] )
                    elif isinstance(obj[k],list):
                        self[k] = [self[k]] + obj[k]
                    elif isinstance(self[k],Object) and isinstance(obj[k],Object):
                        self[k].merge( obj[k] )
                    elif isinstance(self[k],Object) and isinstance(obj[k],dict):
                        self[k].merge( obj[k] )
                    else:
                        self[k] = [ self[k], obj[k] ]
                else:
                    if isinstance(obj[k],dict):
                        self[k] = Object( obj[k] )
                    else:
                        self[k] = obj[k]
        return self

def test01():
    class UObject( Object ):
        pass
    obj = Object({1:2})
    d = {}
    d.update({
        "a": 1,
        "b": {
            "c": 2,
            "d": [ 3, 4, 5 ],
            "e": [ [6,7], (8,9) ],
            "self": d,
        },
        1: 10,
        "1": 11,
        "obj": obj,
    })
    x = UObject(d)


    assert x.a == x["a"] == 1
    assert x.b.c == x["b"]["c"] == 2
    assert x.b.d[0] == 3
    assert x.b.d[1] == 4
    assert x.b.e[0][0] == 6
    assert x.b.e[1][0] == 8
    assert x[1] == 10
    assert x["1"] == 11
    assert x[1] != x["1"]
    assert id(x) == id(x.b.self.b.self) == id(x.b.self)
    assert x.b.self.a == x.b.self.b.self.a == 1

    x.x = 12
    assert x.x == x["x"] == 12
    x.y = {"a":13,"b":[14,15]}
    assert x.y.a == 13
    assert x.y.b[0] == 14

def test02():
    x = Object({
        "a": {
            "b": 1,
            "c": [ 2, 3 ]
        },
        1: 6,
        2: [ 8, 9 ],
        3: 11,
    })
    y = Object({
        "a": {
            "b": 4,
            "c": [ 5 ]
        },
        1: 7,
        2: 10,
        3: [ 12 , 13 ],
    })
    z = {
        3: 14,
        2: 15,
        "a": {
            "b": 16,
            "c": 17,
        }
    }
    x.merge( y, z )
    assert 2 in x.a.c
    assert 3 in x.a.c
    assert 5 in x.a.c
    assert 1 in x.a.b
    assert 4 in x.a.b
    assert 8 in x[2]
    assert 9 in x[2]
    assert 10 in x[2]
    assert 11 in x[3]
    assert 12 in x[3]
    assert 13 in x[3]
    assert 14 in x[3]
    assert 15 in x[2]
    assert 16 in x.a.b
    assert 17 in x.a.c

if __name__ == '__main__':
    test01()
    test02()

4

এই ছোট্ট দৃষ্টান্তটির আমার সংস্করণটি আপলোড করতে চেয়েছিল।

class Struct(dict):
  def __init__(self,data):
    for key, value in data.items():
      if isinstance(value, dict):
        setattr(self, key, Struct(value))
      else:   
        setattr(self, key, type(value).__init__(value))

      dict.__init__(self,data)

এটি শ্রেণিতে আমদানি করা ধরণের বৈশিষ্ট্যগুলি সংরক্ষণ করে। আমার একমাত্র উদ্বেগ হ'ল অভিধানটি আপনার বিশ্লেষণের মধ্য থেকে রচনাগুলি ওভাররাইট করা হবে। তবে অন্যথায় শক্ত মনে হচ্ছে!


যদিও একটি দুর্দান্ত ধারণা, এটি ওপির উদাহরণের জন্য কাজ করে বলে মনে হচ্ছে না, বাস্তবে এটি অভিধানে পাস করা সংশোধন করার কথা রয়েছে! আসলে, df.aএমনকি কাজ করে না।
অ্যান্ডি হেডেন

4

এটি খুব ভাল কাজ করে

class DObj(object):
    pass

dobj = Dobj()
dobj.__dict__ = {'a': 'aaa', 'b': 'bbb'}

print dobj.a
>>> aaa
print dobj.b
>>> bbb

3

সাইলেন্টগোস্টের মূল পরামর্শটি বাস্তবায়নের আরও একটি উপায় এখানে রয়েছে:

def dict2obj(d):
  if isinstance(d, dict):
    n = {}
    for item in d:
      if isinstance(d[item], dict):
        n[item] = dict2obj(d[item])
      elif isinstance(d[item], (list, tuple)):
        n[item] = [dict2obj(elem) for elem in d[item]]
      else:
        n[item] = d[item]
    return type('obj_from_dict', (object,), n)
  else:
    return d

3

রবার্তোর স্নিপেটের উপর ভিত্তি করে আমার কী কাজ করেছে: তার ভিত্তিতে আমার যে বিষয়টি রবার্টিকভাবে ডিক্টের একটি তালিকাকে অবজেক্টের তালিকায় রূপান্তর করা দরকার ছিল তাতে আমি হোঁচট খেয়েছি:

def dict2obj(d):
    if isinstance(d, dict):
        n = {}
        for item in d:
            if isinstance(d[item], dict):
                n[item] = dict2obj(d[item])
            elif isinstance(d[item], (list, tuple)):
                n[item] = [dict2obj(elem) for elem in d[item]]
            else:
                n[item] = d[item]
        return type('obj_from_dict', (object,), n)
    elif isinstance(d, (list, tuple,)):
        l = []
        for item in d:
            l.append(dict2obj(item))
        return l
    else:
        return d

নোট করুন যে কোনও টিপল সুস্পষ্ট কারণে তার তালিকার সমতুল্যে রূপান্তরিত হবে।

আশা করি আপনারা সমস্ত উত্তর আমার পক্ষে যেমনটি করেছে তেমন কাউকে এটি সহায়তা করবে।


3

কি শুধু আপনার বরাদ্দ dictকরার __dict__একটি খালি বস্তুর?

class Object:
    """If your dict is "flat", this is a simple way to create an object from a dict

    >>> obj = Object()
    >>> obj.__dict__ = d
    >>> d.a
    1
    """
    pass

অবশ্যই আপনি আপনার নেস্টেড ডিক্ট উদাহরণটিতে ব্যর্থ হন যতক্ষণ না আপনি ডরকে পুনরাবৃত্তি করে হাঁটা:

# For a nested dict, you need to recursively update __dict__
def dict2obj(d):
    """Convert a dict to an object

    >>> d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}
    >>> obj = dict2obj(d)
    >>> obj.b.c
    2
    >>> obj.d
    ["hi", {'foo': "bar"}]
    """
    try:
        d = dict(d)
    except (TypeError, ValueError):
        return d
    obj = Object()
    for k, v in d.iteritems():
        obj.__dict__[k] = dict2obj(v)
    return obj

এবং আপনার উদাহরণ তালিকার উপাদানটি সম্ভবত একটি হতে বোঝানো হয়েছিল Mapping, (কী, মান) জোড়ার জোড়ার একটি তালিকা:

>>> d = {'a': 1, 'b': {'c': 2}, 'd': [("hi", {'foo': "bar"})]}
>>> obj = dict2obj(d)
>>> obj.d.hi.foo
"bar"

2

এখানে আরও একটি বাস্তবায়ন রয়েছে:

class DictObj(object):
    def __init__(self, d):
        self.__dict__ = d

def dict_to_obj(d):
    if isinstance(d, (list, tuple)): return map(dict_to_obj, d)
    elif not isinstance(d, dict): return d
    return DictObj(dict((k, dict_to_obj(v)) for (k,v) in d.iteritems()))

[সম্পাদনা] তালিকার মধ্যে ডিকটগুলি হ্যান্ডল করার বিষয়ে বিস্মৃত বিট, কেবলমাত্র অন্যান্য নকল নয়। সংশোধন করা হয়েছে।


মনে রাখবেন যে উত্স অভিধানে ডিক সেট করার অর্থ হ'ল ফলস্বরূপ বস্তুর উপর বৈশিষ্ট্যের কোনও পরিবর্তনগুলিও সেই অভিধানকে প্রভাবিত করবে যা বস্তুটি তৈরি করেছে এবং তদ্বিপরীত। অভিধানটি অবজেক্ট তৈরি করা ব্যতীত অন্য কোনও কিছুর জন্য ব্যবহার করা হলে এটি অপ্রত্যাশিত ফলাফল হতে পারে।
মার্ক রডি

@ মার্ক: আসলে, একই ডিক অবজেক্টের মধ্য দিয়ে যাওয়ার পরিবর্তে প্রতিবার ডিকটবজে একটি নতুন অভিধান পাস করা হচ্ছে, সুতরাং এটি আসলে ঘটবে না। এটা এই কাজ করতে neccessary এর হিসাবে আমি অনুবাদ করতে প্রয়োজন মূল্যবোধের পাশাপাশি একটি অভিধান মধ্যে, তাই এটি নিজেকে mutating ছাড়া মূল অভি বস্তুর মধ্য দিয়ে পাস করার অসম্ভব।
ব্রায়ান

এটির জন্য বেশ কয়েকটি উত্তর রয়েছে, গৃহীত উত্তরগুলি এটি পুনরাবৃত্ত হবে না বা তালিকাগুলি পরিচালনা করবে বলে মনে হয় নি। আমি তাদের সবার মধ্যে পড়েছি এবং এটি প্রথম দর্শনে সবচেয়ে সহজ দেখাচ্ছে, আমি পরীক্ষা করেছি এবং এটি কার্যকর হয়েছে। দুর্দান্ত উত্তর।
সর্বদা প্রশিক্ষণ

2
class Struct(dict):
    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

    def __setattr__(self, name, value):
        self[name] = value

    def copy(self):
        return Struct(dict.copy(self))

ব্যবহার:

points = Struct(x=1, y=2)
# Changing
points['x'] = 2
points.y = 1
# Accessing
points['x'], points.x, points.get('x') # 2 2 2
points['y'], points.y, points.get('y') # 1 1 1
# Accessing inexistent keys/attrs 
points['z'] # KeyError: z
points.z # AttributeError: z
# Copying
points_copy = points.copy()
points.x = 2
points_copy.x # 1

2

এটি সম্পর্কে:

from functools import partial
d2o=partial(type, "d2o", ())

এটি এর পরে এটি ব্যবহার করা যেতে পারে:

>>> o=d2o({"a" : 5, "b" : 3})
>>> print o.a
5
>>> print o.b
3

2

আমি মনে করি একটি ডিক সংখ্যা, স্ট্রিং এবং ডিক নিয়ে গঠিত বেশিরভাগ সময় যথেষ্ট। সুতরাং আমি সেই পরিস্থিতিকে অগ্রাহ্য করি যা ডুপের চূড়ান্ত মাত্রায় টিপলস, তালিকাগুলি এবং অন্যান্য ধরণের উপস্থিত হয় না।

উত্তরাধিকার বিবেচনা করে, পুনরাবৃত্তির সাথে একত্রিত হয়ে এটি মুদ্রণের সমস্যাটি সুবিধামতভাবে সমাধান করে এবং ডেটা অনুসন্ধানের দুটি উপায় সরবরাহ করে, একটি উপায়ে সম্পাদনা করার এক উপায়।

নীচের উদাহরণটি দেখুন, একটি ডিক যা শিক্ষার্থীদের সম্পর্কে কিছু তথ্য বর্ণনা করে:

group=["class1","class2","class3","class4",]
rank=["rank1","rank2","rank3","rank4","rank5",]
data=["name","sex","height","weight","score"]

#build a dict based on the lists above
student_dic=dict([(g,dict([(r,dict([(d,'') for d in data])) for r in rank ]))for g in group])

#this is the solution
class dic2class(dict):
    def __init__(self, dic):
        for key,val in dic.items():
            self.__dict__[key]=self[key]=dic2class(val) if isinstance(val,dict) else val


student_class=dic2class(student_dic)

#one way to edit:
student_class.class1.rank1['sex']='male'
student_class.class1.rank1['name']='Nan Xiang'

#two ways to query:
print student_class.class1.rank1
print student_class.class1['rank1']
print '-'*50
for rank in student_class.class1:
    print getattr(student_class.class1,rank)

ফলাফল:

{'score': '', 'sex': 'male', 'name': 'Nan Xiang', 'weight': '', 'height': ''}
{'score': '', 'sex': 'male', 'name': 'Nan Xiang', 'weight': '', 'height': ''}
--------------------------------------------------
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
{'score': '', 'sex': 'male', 'name': 'Nan Xiang', 'weight': '', 'height': ''}
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}
{'score': '', 'sex': '', 'name': '', 'weight': '', 'height': ''}

2

সাধারণত আপনি আপনার বস্তুতে ডিকের শ্রেণিবিন্যাস আয়না করতে চান তবে তালিকা বা টিপলগুলি নয় যা সাধারণত সর্বনিম্ন স্তরে থাকে। সুতরাং আমি এটি এইভাবে করেছি:

class defDictToObject(object):

    def __init__(self, myDict):
        for key, value in myDict.items():
            if type(value) == dict:
                setattr(self, key, defDictToObject(value))
            else:
                setattr(self, key, value)

সুতরাং আমরা কি:

myDict = { 'a': 1,
           'b': { 
              'b1': {'x': 1,
                    'y': 2} },
           'c': ['hi', 'bar'] 
         }

এবং পেতে:

x.b.b1.x 1

x.c ['হাই', 'বার']


1

আমার অভিধানটি এই ফর্ম্যাটটির:

addr_bk = {
    'person': [
        {'name': 'Andrew', 'id': 123, 'email': 'andrew@mailserver.com',
         'phone': [{'type': 2, 'number': '633311122'},
                   {'type': 0, 'number': '97788665'}]
        },
        {'name': 'Tom', 'id': 456,
         'phone': [{'type': 0, 'number': '91122334'}]}, 
        {'name': 'Jack', 'id': 7788, 'email': 'jack@gmail.com'}
    ]
}

যেমন দেখা যায়, আমি নেস্টেড ডিকশনারি এবং ডিক্টের তালিকা পেয়েছি । এর কারণ অ্যাডর_বি কে প্রোটোকল বাফার ডেটা থেকে ডিকোড করা হয়েছিল যা lwpb.codec ব্যবহার করে পাইথন ডিকে রূপান্তরিত হয়েছিল। Optionচ্ছিক ক্ষেত্র রয়েছে (যেমন ইমেল => যেখানে কী অনুপলব্ধ হতে পারে) এবং পুনরাবৃত্তি ক্ষেত্র (যেমন ফোন => ডিকের তালিকায় রূপান্তরিত)।

আমি উপরোক্ত সমস্ত প্রস্তাবিত সমাধান চেষ্টা করেছি। কিছু নেস্টেড ডিকশনারিগুলিকে ভালভাবে পরিচালনা করে না। অন্যরা সহজেই অবজেক্টের বিশদটি মুদ্রণ করতে পারে না।

ডাউ স্ট্রাউসের একটিমাত্র সমাধান, ডিক্টোবজ (ডিক্ট), সবচেয়ে ভাল কাজ করে।

যখন কীটি পাওয়া যায় না তখন আমি এটি পরিচালনা করতে কিছুটা বাড়িয়েছি:

# Work the best, with nested dictionaries & lists! :)
# Able to print out all items.
class dict2obj_new(dict):
    def __init__(self, dict_):
        super(dict2obj_new, self).__init__(dict_)
        for key in self:
            item = self[key]
            if isinstance(item, list):
                for idx, it in enumerate(item):
                    if isinstance(it, dict):
                        item[idx] = dict2obj_new(it)
            elif isinstance(item, dict):
                self[key] = dict2obj_new(item)

    def __getattr__(self, key):
        # Enhanced to handle key not found.
        if self.has_key(key):
            return self[key]
        else:
            return None

তারপরে, আমি এটি দিয়ে পরীক্ষা করেছি:

# Testing...
ab = dict2obj_new(addr_bk)

for person in ab.person:
  print "Person ID:", person.id
  print "  Name:", person.name
  # Check if optional field is available before printing.
  if person.email:
    print "  E-mail address:", person.email

  # Check if optional field is available before printing.
  if person.phone:
    for phone_number in person.phone:
      if phone_number.type == codec.enums.PhoneType.MOBILE:
        print "  Mobile phone #:",
      elif phone_number.type == codec.enums.PhoneType.HOME:
        print "  Home phone #:",
      else:
        print "  Work phone #:",
      print phone_number.number

1

" অজগর: কীভাবে একটি শ্রেণিতে সম্পত্তি গতিশীলভাবে যুক্ত করা যায়? " - এ আমার উত্তর বন্ধ করে দেওয়া :

class data(object):
    def __init__(self,*args,**argd):
        self.__dict__.update(dict(*args,**argd))

def makedata(d):
    d2 = {}
    for n in d:
        d2[n] = trydata(d[n])
    return data(d2)

def trydata(o):
    if isinstance(o,dict):
        return makedata(o)
    elif isinstance(o,list):
        return [trydata(i) for i in o]
    else:
        return o

আপনি makedataযে অভিধানটি রূপান্তর করতে চান তা ডাকে বা হতে পারেtrydata ইনপুট হিসাবে আপনি কী প্রত্যাশা করেন তার উপর নির্ভর করে এবং এটি কোনও ডেটা অবজেক্টকে ছড়িয়ে দেয়।

মন্তব্য:

  • আপনি এলিফ যোগ করতে পারেন trydata আরও কার্যকারিতা প্রয়োজন হলে আপনি পারেন।
  • অবশ্যই আপনি চাইলে এটি কাজ করবে না x.a = {} বা অনুরূপ ।
  • আপনি যদি কেবল পঠনযোগ্য সংস্করণ চান তবে মূল উত্তর থেকে বর্গ ডেটা ব্যবহার করুন ।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.