কীভাবে বিন্দু ব্যবহার করবেন “।” অভিধানের সদস্যদের অ্যাক্সেস করতে?


282

পাইথন অভিধানের সদস্যদের কীভাবে বিন্দুর মাধ্যমে অ্যাক্সেসযোগ্য করব?

উদাহরণস্বরূপ, লেখার পরিবর্তে mydict['val'], আমি লিখতে চাই mydict.val

এছাড়াও আমি নেস্টেড ডিক্টগুলি এইভাবে অ্যাক্সেস করতে চাই। উদাহরণ স্বরূপ

mydict.mydict2.val 

উল্লেখ করা হবে

mydict = { 'mydict2': { 'val': ... } }

20
লোকেরা নেস্টেড ডিক্টস ব্যবহার করে এমন অনেক পরিস্থিতিতে ডাইপটস দ্বারা ডাইপটস দ্বারা কী হিসাবে টিপস যুক্ত করা হয়, যেখানে d[a][b][c]প্রতিস্থাপন করা হয় d[a, b, c]
মাইক গ্রাহাম

7
এটি যাদু নয়: foo = {}; foo [1,2,3] = "এক, দুই, তিন!"; foo.keys () => [(1,2,3)]
ব্রায়ান ওকলে

10
কি দারুন. বাহ আবার। আমি জানতাম না যে টিপলস ডিকের চাবি হতে পারে। বাহ তৃতীয়বার।
বোড্যাসিডো

3
"হ্যাশযোগ্য" যে কোনও বস্তু ডিকের কী হিসাবে ব্যবহৃত হতে পারে। বেশিরভাগ অপরিবর্তনীয় বস্তুগুলি হ্যাশযোগ্য, তবে কেবল যদি তাদের সমস্ত বিষয়বস্তু হ্যাশযোগ্য হয়। ডি [1, 2, 3] কোডটি কাজ করে কারণ "," হ'ল "একটি টুপল অপারেটর তৈরি করুন"; এটি ডি এর সমান ([1, 2, 3)]। টিউপল ঘোষণার আশেপাশে প্যারেন্টিসগুলি প্রায়শই areচ্ছিক।
ল্যারি হেস্টিংস

6
কীটি কী নিজেই বিন্দু আছে সে ক্ষেত্রে বিবেচনা করেছেন - {"my.key":"value"}? বা যখন কীটি কোনও কীওয়ার্ড হয় যেমন "থেকে"? আমি এটিকে কয়েকবার বিবেচনা করেছি এবং এটি বেনিফিটের চেয়ে বেশি সমস্যা এবং সমস্যা সমাধানের চেষ্টা করে।
টডর মিনাকভ

উত্তর:


147

আমি সবে তৈরি এই ক্লাসটি ব্যবহার করে আপনি এটি করতে পারেন। এই শ্রেণীর সাহায্যে আপনি Mapঅন্য অভিধানের মতো বস্তুটি (জসন সিরিয়ালাইজেশন সহ) বা ডট নোটেশন সহ ব্যবহার করতে পারেন । আমি আপনাকে সাহায্য আশা করি:

class Map(dict):
    """
    Example:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self[k] = v

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

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

m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
# Or
m['new_key'] = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']

21
উপর পাইথন 3 আমি কাজ আপডেট করার .iteritems()জন্য.items()
berto

13
দ্রষ্টব্য যে এটি সাধারণ প্রত্যাশাগুলির থেকে আলাদাভাবে আচরণ করবে যেটিতে AttributeErrorযদি বৈশিষ্ট্যটি বিদ্যমান না থাকে তবে তা উত্থাপিত হবে না । পরিবর্তে এটি ফিরে আসবে None
mic_e

গেটসেট এবং সেটসেট যুক্ত করার পরামর্শ দিন যাতে গভীর অনুলিপি এবং অন্যান্য সিস্টেমগুলি এটি সমর্থন করতে পারে।
ব্যবহারকারী 1363990

4
আপনি আপনার নির্মাতাকে সহজ করতে পারেন self.update(*args,**kwargs)। এছাড়াও, আপনি যোগ করতে পারেন __missing__(self,key): value=self[key]= type(self)(); return value। তারপরে আপনি বিন্দু চিহ্নিতকরণ ব্যবহার করে নিখোঁজ এন্ট্রি যুক্ত করতে পারেন। আপনি যদি এটি চয়নযোগ্য হতে চান তবে আপনি যোগ করতে পারেন __getstate__এবং__setstate__
জেনস মুঙ্ক

1
এটি hasattr(Map, 'anystring') is true. which means the hasattr would always return True due to overriding __getattr__` তৈরি করবে
জিয়াও

264

আমি এটিকে সর্বদা একটি ব্যবহারকারীর ফাইলে রেখেছি। আপনি এটি নিজের ক্লাসেও মিশ্রণ হিসাবে ব্যবহার করতে পারেন।

class dotdict(dict):
    """dot.notation access to dictionary attributes"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

mydict = {'val':'it works'}
nested_dict = {'val':'nested works too'}
mydict = dotdict(mydict)
mydict.val
# 'it works'

mydict.nested = dotdict(nested_dict)
mydict.nested.val
# 'nested works too'

5
খুব সহজ উত্তর, দুর্দান্ত! আইপিথনের কাজের ট্যাব-সমাপ্তির জন্য আমার কী প্রয়োজন তা জানতে আপনি কি ঘটেন? শ্রেণীর __dir __ (স্ব) বাস্তবায়ন করতে হবে তবে কোনওভাবে আমি এটি কাজ করতে পারি না।
andreas-h

8
সরলতার জন্য +1। তবে নেস্টেড ডিক্টসে কাজ করছে বলে মনে হচ্ছে না। d = {'foo': {'bar': 'baz'}}; d = dotdict(d); d.foo.barএকটি বৈশিষ্ট্য ত্রুটি নিক্ষেপ করে, তবে ঠিকঠাক d.fooকাজ করে।
tmthyjames

2
হ্যাঁ এটি জটিল নেস্টেড কাঠামোর জন্য কাজ করে না।
ডেভিড

16
@ টমথিজেমস আপনি ডট স্বরলিপি সহ পুনরাবৃত্তভাবে অ্যাট্রিবিউটগুলি অ্যাক্সেসের জন্য গেটর পদ্ধতিতে ডটডিক্ট টাইপ অবজেক্টটি সহজেই ফিরে আসতে পারেন: python class DotDict(dict): """dot.notation access to dictionary attributes""" def __getattr__(*args): val = dict.get(*args) return DotDict(val) if type(val) is dict else val __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__
টিএমকাসুন

4
এটির পরীক্ষা-নিরীক্ষার পরে, এটি getআসলে একটি খারাপ ধারণা বলে মনে হচ্ছে যেহেতু এটি Noneহারিয়ে যাওয়া আইটেমগুলির জন্য ত্রুটি বাড়ানোর পরিবর্তে ফিরে আসবে ...
নিকটজেনস

117

এর dotmapমাধ্যমে ইনস্টল করুনpip

pip install dotmap

এটি আপনি যা করতে চান তা এবং উপশ্রেণীগুলি সমস্ত কিছু করে dict, তাই এটি একটি সাধারণ অভিধানের মতো পরিচালনা করে:

from dotmap import DotMap

m = DotMap()
m.hello = 'world'
m.hello
m.hello += '!'
# m.hello and m['hello'] now both return 'world!'
m.val = 5
m.val2 = 'Sam'

তার উপরে, আপনি এটিকে এবং dictঅবজেক্ট থেকে রূপান্তর করতে পারেন :

d = m.toDict()
m = DotMap(d) # automatic conversion in constructor

এর অর্থ হল যে আপনি যে কোনও কিছু অ্যাক্সেস করতে চান তা যদি ইতিমধ্যে dictফর্মে থাকে তবে আপনি DotMapসহজেই অ্যাক্সেসের জন্য এটিকে রূপান্তর করতে পারেন :

import json
jsonDict = json.loads(text)
data = DotMap(jsonDict)
print data.location.city

অবশেষে, এটি স্বয়ংক্রিয়ভাবে নতুন শিশুদের DotMapউদাহরণ তৈরি করে যাতে আপনি এই জাতীয় জিনিসগুলি করতে পারেন:

m = DotMap()
m.people.steve.age = 31

গুচ্ছের সাথে তুলনা

সম্পূর্ণ প্রকাশ: আমি ডটম্যাপের নির্মাতা । আমি এটি তৈরি করেছি কারণ Bunchএই বৈশিষ্ট্যগুলি অনুপস্থিত ছিল

  • মনে রাখবেন অর্ডার আইটেম যুক্ত করা হয় এবং সেই ক্রমে পুনরাবৃত্তি
  • স্বয়ংক্রিয়ভাবে শিশু DotMapতৈরি করা, যখন আপনার অনেক শ্রেণিবদ্ধ থাকে তখন সময় সাশ্রয় করে এবং ক্লিনার কোড তৈরি করে
  • একটি থেকে গঠন dictএবং পুনরাবৃত্তভাবে সমস্ত শিশু dictদৃষ্টান্ত রূপান্তরDotMap

2
:-) আপনি কী দিয়ে ইতিমধ্যে নাম বিন্দু আছে কি দিয়ে এটি কাজ করতে পারেন? {"test.foo": "bar"}এর মাধ্যমে অ্যাক্সেস করা যায় mymap.test.fooএটি দুর্দান্ত। একটি ফ্ল্যাট মানচিত্রকে একটি গভীর মানচিত্রে রূপান্তর করতে কিছুটা পুনঃসংশোধন লাগবে তারপরে এটিতে ডটম্যাপ প্রয়োগ করুন, তবে এটি মূল্যবান!
dlite922

ঝরঝরে। জুপিটার নোটবুকের কীগুলি দিয়ে ট্যাব তালিকা তৈরি / সমাপ্তির কাজ করার কোনও উপায়? ইন্টারেক্টিভ ব্যবহারের জন্য ডট-স্টাইল অ্যাক্সেস সবচেয়ে মূল্যবান।
দিমিত্রি

@ দিমিত্রি কুল পণ্য। এর আগে এর আগে কখনও শুনিনি, সুতরাং কীভাবে এর স্বপূরণ কাজটি করা যায় তা সম্পর্কে আমি নিশ্চিত নই। আমি DotMapস্বতঃসিদ্ধ কাজগুলি সর্বোত্তম ব্যবহার করে সম্মত । আমি সাবলাইম টেক্সট ব্যবহার করি, যা পূর্বে টাইপ করা কীওয়ার্ডগুলি স্বয়ংক্রিয়ভাবে পূর্ণ হয়।
ক্রিস রেডফোর্ড

1
আমি দেখতে পাচ্ছি যে এর মতো **kwargsবা যেমন এর জন্য অভিধান নিষ্কাশন অভাবের c = {**a, **b}। আসলে, এটি নিঃশব্দে ব্যর্থ হয়, এটি বের করার সময় এটি একটি খালি অভিধানের মতো আচরণ করে।
সাইমন স্ট্রিচার

@ সিমোনস্ট্র্রিচার আমি এটি দিয়ে পরীক্ষা করেছি m = DotMap(); m.a = 2; m.b = 3; print('{a} {b}'.format(**m));এবং আমি প্রত্যাশিত হয়েছি 2 3। আপনার যদি প্রমাণিত ভাঙা মামলা রয়েছে যা এর জন্য কাজ করে dict()তবে তা নয় DotMap(), দয়া করে আপনার কোডটি গিটহাবের সমস্যা ট্যাবে জমা দিন।
ক্রিস রেডফোর্ড 16'18

56

ডিক থেকে প্রাপ্ত এবং বাস্তবায়ন __getattr__এবং __setattr__

অথবা আপনি গুচ্ছ ব্যবহার করতে পারেন যা খুব অনুরূপ।

আমি মনে করি না যে বিল্ট-ইন ডিক ক্লাসটি বানরপ্যাচ করা সম্ভব।


2
মনকিপ্যাচ বলতে কী বোঝায়? আমি এটি সম্পর্কে শুনেছি কিন্তু ব্যবহার করা হয়নি। (দুঃখিত যে আমি এই জাতীয় নবীনতর প্রশ্ন জিজ্ঞাসা করি, আমি প্রোগ্রামিংয়ের সাথে এখনও তেমন ভাল নই (আমি কেবল ২ য় বর্ষের শিক্ষার্থী)))
বোডাসিডো

9
Monkeypatching পাইথনের গতিশীলতা (বা যে কোনও ভাষা) ব্যবহার করছে যা সাধারণত উত্স কোডে সংজ্ঞায়িত হয় change এটি ক্লাসগুলি তৈরি হওয়ার পরে সংজ্ঞা পরিবর্তন করার ক্ষেত্রে বিশেষত প্রযোজ্য।
মাইক গ্রাহাম

আপনি যদি এই কার্যকারিতাটি অনেক বেশি ব্যবহার করেন তবে গুচ্ছের গতি থেকে সাবধান থাকুন। আমি এটি প্রায়শই ঘন ঘন ব্যবহার করছিলাম এবং এটি আমার অনুরোধের সময়ের এক তৃতীয়াংশ গ্রাস করে। এর আরও বিশদ ব্যাখ্যার জন্য আমার উত্তরটি দেখুন।
জয়ডি 3 ই

22

ফ্যাব্রিক একটি দুর্দান্ত, ন্যূনতম বাস্তবায়ন আছে । নেস্টেড অ্যাক্সেসের অনুমতি দেওয়ার জন্য এটি প্রসারিত করে আমরা একটি ব্যবহার করতে পারি defaultdictএবং ফলাফলটি এরকম কিছু দেখায়:

from collections import defaultdict

class AttributeDict(defaultdict):
    def __init__(self):
        super(AttributeDict, self).__init__(AttributeDict)

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

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

নিম্নলিখিত হিসাবে এটি ব্যবহার করুন:

keys = AttributeDict()
keys.abc.xyz.x = 123
keys.abc.xyz.a.b.c = 234

"ডিক থেকে ডেরিভ এবং বাস্তবায়ন __getattr__এবং __setattr__" এর কুগেলের উত্তরের বিষয়ে এটি কিছুটা ব্যাখ্যা করে এখন আপনি জানেন কিভাবে!


1
যে এক দুর্দান্ত!
থমাস ক্লিঞ্জার

ডিফল্টডিক্টিক্ট অন্তর্ভুক্ত করে ভাল লাগছে - তবে এটি স্ক্র্যাচ থেকে ডিক শুরু করার সময় কেবল কাজ করে বলে মনে হয়। আমাদের যদি বিদ্যমান বিদ্যমান ডিককে পুনরাবৃত্তভাবে "ডটডিক্ট" রূপান্তর করতে হয়। এখানে একটি বিকল্প dotdictযা বিদ্যমান dictঅবজেক্টকে পুনরাবৃত্তিতে রূপান্তর করতে দেয় : gist.github.com/miku/…
মিকু

19

আমি এটি চেষ্টা করেছি:

class dotdict(dict):
    def __getattr__(self, name):
        return self[name]

__getattribute__আপনিও চেষ্টা করতে পারেন

প্রতিটি ডিককে একটি ধরণের ডটডিক্ট তৈরি করুন যথেষ্ট ভাল, যদি আপনি এটি একটি মাল্টি-লেয়ার ডিক থেকে শুরু করতে চান তবে __init__খুব কার্যকর করার চেষ্টা করুন ।


ওফস, @ কুজেলের উত্তর একই রকম।
tdihp

1
তিডিহপ, আমি আপনার উত্তরটি এখনও পছন্দ করি কারণ আমি এটি দ্রুত বুঝতে পেরেছিলাম - এর আসল কোড রয়েছে।
ইগাল

1
প্রকৃত কোডের জন্য +1। তবে @ কুগেলের গুচ্ছ ব্যবহারের পরামর্শটিও খুব ভাল।
ড্যানিড

এটি def docdict(name):আগে রাখার পরে একটি ফাংশনটির ভিতরে এটি এম্বেড করার জন্য আমি দরকারী এবং তারপরে - যদি in if isinstance (নাম, ডিক): ফিরতি ডটডিক্ট (নাম) ফেরতের নাম `
ড্যানিয়েল মোসকোভিচ

দুর্দান্ত সরল উদাহরণ .. আমি এটি কিছুটা প্রসারিত করেছি যাতে @ ড্যানিয়েলমোস্কোভিচের অনুরূপ নেস্টেড ডিক সহজেই বেঁধে রাখা হয়, তবে ইন্টি, স্ট্রিং ইত্যাদির জন্যও পাতার নোডগুলি সঠিকভাবে ফেরত দেয় ... বা পাওয়া না গেলে নালclass dotdict(dict): def __getattr__(self, name): if name not in self: return None elif type(self[name]) is dict: return JsonDot(self[name]) else: return self[name]
ডি সায়ভার্স

11

না। অ্যাট্রিবিউট অ্যাক্সেস এবং ইনডেক্সিং পাইথনের পৃথক জিনিস এবং আপনার উচিত হবে না যে তারা এটি সম্পাদন করুন। namedtupleআপনার কাছে এমন কিছু রয়েছে যা অ্যাক্সেসযোগ্য বৈশিষ্ট্যযুক্ত থাকতে হবে এবং []ডিক্ট থেকে কোনও আইটেম প্রাপ্তির জন্য স্বরলিপিটি ব্যবহার করা উচিত যদি একটি শ্রেণি তৈরি করুন (সম্ভবত একটি দ্বারা তৈরি করা ) ।


উত্তর করার জন্য ধন্যবাদ. তবে এই প্রশ্নটি একবার দেখুন যা আমি কেবল জিজ্ঞাসা করেছি: স্ট্যাকওভারফ্লো / প্রশ্ন / 2352252/… মাকো টেমপ্লেটগুলিতে জটিল ডেটা কাঠামো অ্যাক্সেস করার .পরিবর্তে ব্যবহার করা ভাল ধারণা বলে মনে হচ্ছে []
বোড্যাসিডো

2
আমি এর জন্য একটি ব্যবহারের কেস দেখতে পাচ্ছি; আসলে, আমি এটি কয়েক সপ্তাহ আগে করেছি did আমার ক্ষেত্রে আমি এমন একটি জিনিস চেয়েছিলাম যা আমি বিন্দু চিহ্নিতকরণ সহ বৈশিষ্ট্যগুলিতে অ্যাক্সেস করতে পারি। আমি ডিকের কাছ থেকে উত্তরাধিকার সূত্রে পাওয়া খুব সহজ পেয়েছি তাই আমি সমস্ত ডিক বৈশিষ্ট্যগুলি অন্তর্নির্মিত পেয়েছি, তবে এই অবজেক্টের সর্বজনীন ইন্টারফেস ডট স্বরলিপি ব্যবহার করে (এটি কিছু স্থিতিশীল ডেটাতে মূলত পঠনযোগ্য কেবল ইন্টারফেস)। আমার ব্যবহারকারীরা 'foo.bar' এর সাথে 'foo ["বার"]' এর চেয়ে অনেক বেশি সুখী এবং আমি খুশি যে আমি ডিক ড্যাটাটাইপের বৈশিষ্ট্যগুলি পিগি-ব্যাক করতে পারি।
ব্রায়ান ওকলে

10
আপনি ইতিমধ্যে ভাল পাইথন স্টাইলটি জানেন: আমরা আপনাকে বলছি, ডিকের মানগুলি বৈশিষ্ট্য বলে ভান করবেন না। এটা খারাপ অভ্যাস। উদাহরণস্বরূপ, আপনি যদি ডিকের বিদ্যমান বৈশিষ্ট্য হিসাবে "আইটেমস" বা "গেট" বা "পপ" এর মতো একই নামের সাথে একটি মান সংরক্ষণ করতে চান তবে? সম্ভবত বিভ্রান্তিকর কিছু। সুতরাং এটি করবেন না!
ল্যারি হেস্টিংস

5
ওহো, আমি 'আইটেম', 'পাবেন' বা 'পপ'র মতো বৈশিষ্ট্যগুলি ভুলে গিয়েছিলাম। এই গুরুত্বপূর্ণ উদাহরণ আনার জন্য ধন্যবাদ!
বোডাসিদো

5
@ গ্যাবে, অনেক দিন হয়েছে ... তবে আমার মনে হয় এটি বলাই বাহুল্য। এটি "জেএসে যথেষ্ট ভাল" নয়: এটি "জেএসে যথেষ্ট ভয়ঙ্কর"। প্রোটোটাইপিক চেইনে অন্যান্য গুরুত্বপূর্ণ বৈশিষ্ট্যের মতো একই নামযুক্ত কী / অ্যাটর সংরক্ষণ করার সময় এটি মজার হয়।
বিগুছাচ

11

আপনি যদি আপনার সংশোধিত অভিধানকে আচার করতে চান তবে উপরের উত্তরে আপনাকে কয়েকটি রাষ্ট্রীয় পদ্ধতি যুক্ত করতে হবে:

class DotDict(dict):
    """dot.notation access to dictionary attributes"""
    def __getattr__(self, attr):
        return self.get(attr)
    __setattr__= dict.__setitem__
    __delattr__= dict.__delitem__

    def __getstate__(self):
        return self

    def __setstate__(self, state):
        self.update(state)
        self.__dict__ = self

বাছুর সম্পর্কে মন্তব্য করার জন্য ধন্যবাদ। আমি এই ত্রুটি দ্বারা পাগল হয়েছি এবং কেবল বুঝতে পেরেছিলাম যে এটি এই সমস্যার কারণেই!
শাগরু

আপনি কপি.দীপকপি ব্যবহার করার সময়ও ঘটে। এই সংযোজন প্রয়োজন।
ব্যবহারকারী 1363990

__getattr__ = dict.get
সরলকরণ

9

কুগেলের উত্তরের উপর ভিত্তি করে মাইক গ্রাহামের সাবধানতার কথাটি বিবেচনায় নেওয়া, আমরা যদি একটি মোড়ক তৈরি করি তবে কী হবে?

class DictWrap(object):
  """ Wrap an existing dict, or create a new one, and access with either dot 
    notation or key lookup.

    The attribute _data is reserved and stores the underlying dictionary.
    When using the += operator with create=True, the empty nested dict is 
    replaced with the operand, effectively creating a default dictionary
    of mixed types.

    args:
      d({}): Existing dict to wrap, an empty dict is created by default
      create(True): Create an empty, nested dict instead of raising a KeyError

    example:
      >>>dw = DictWrap({'pp':3})
      >>>dw.a.b += 2
      >>>dw.a.b += 2
      >>>dw.a['c'] += 'Hello'
      >>>dw.a['c'] += ' World'
      >>>dw.a.d
      >>>print dw._data
      {'a': {'c': 'Hello World', 'b': 4, 'd': {}}, 'pp': 3}

  """

  def __init__(self, d=None, create=True):
    if d is None:
      d = {}
    supr = super(DictWrap, self)  
    supr.__setattr__('_data', d)
    supr.__setattr__('__create', create)

  def __getattr__(self, name):
    try:
      value = self._data[name]
    except KeyError:
      if not super(DictWrap, self).__getattribute__('__create'):
        raise
      value = {}
      self._data[name] = value

    if hasattr(value, 'items'):
      create = super(DictWrap, self).__getattribute__('__create')
      return DictWrap(value, create)
    return value

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

  def __getitem__(self, key):
    try:
      value = self._data[key]
    except KeyError:
      if not super(DictWrap, self).__getattribute__('__create'):
        raise
      value = {}
      self._data[key] = value

    if hasattr(value, 'items'):
      create = super(DictWrap, self).__getattribute__('__create')
      return DictWrap(value, create)
    return value

  def __setitem__(self, key, value):
    self._data[key] = value

  def __iadd__(self, other):
    if self._data:
      raise TypeError("A Nested dict will only be replaced if it's empty")
    else:
      return other

8

ব্যবহার SimpleNamespace:

>>> from types import SimpleNamespace   
>>> d = dict(x=[1, 2], y=['a', 'b'])
>>> ns = SimpleNamespace(**d)
>>> ns.x
[1, 2]
>>> ns
namespace(x=[1, 2], y=['a', 'b'])

1
এই পদ্ধতির আরও ভাল কাজ করে। (JSON ফাইল থেকে লোড)
জিইডি

এই অ্যাকাউন্টটি কি নেস্টেড ডিক্টসের জন্য?
মোজিমি

1
নেস্টেড ডিক্টকে সমর্থন করে না। docs.python.org/3.3/library/tyype.html#tyype.SimpleNamespace
কারসন

6

আমি মঞ্চটি পছন্দ করি এবং এটি ডট অ্যাক্সেসের শীর্ষে প্রচুর সহজ বিকল্প দেয়।

আমদানি গুটি

temp_1 = person 'ব্যক্তি': f 'fname': 'সেন্টথিল', 'নাম': 'রামালিংগাম'}

ডিক্ট_মুনচ = মঞ্চ.মুনিচাইফ (অস্থায়ী_1)

dict_munch.person.fname


6

আমি সম্প্রতি ' বক্স জুড়ে এসেছি ' লাইব্রেরি যা একই কাজ করে।

ইনস্টলেশন আদেশ: pip install python-box

উদাহরণ:

from box import Box

mydict = {"key1":{"v1":0.375,
                    "v2":0.625},
          "key2":0.125,
          }
mydict = Box(mydict)

print(mydict.key1.v1)

আমি এটি ডটম্যাপের মতো অন্যান্য বিদ্যমান লাইব্রেরির চেয়ে বেশি কার্যকর বলে মনে করেছি, যা আপনার বড় নেস্ট ডিক্টস থাকলে পাইথন পুনরাবৃত্তি ত্রুটি তৈরি করে।

লাইব্রেরি এবং বিশদে লিঙ্ক: https://pypi.org/project/python-box/


5

__getattr__পাইথন ৩.৪.৩ এ ব্যবহার করুন , খুব সাধারণ

class myDict(dict):
    def __getattr__(self,val):
        return self[val]


blockBody=myDict()
blockBody['item1']=10000
blockBody['item2']="StackOverflow"
print(blockBody.item1)
print(blockBody.item2)

আউটপুট:

10000
StackOverflow

4

ভাষা নিজেই এটি সমর্থন করে না, তবে কখনও কখনও এটি এখনও দরকারী প্রয়োজন। গুচ্ছ রেসিপি ছাড়াও আপনি একটি ছোট্ট পদ্ধতিও লিখতে পারেন যা বিন্দুযুক্ত স্ট্রিং ব্যবহার করে কোনও অভিধানে অ্যাক্সেস করতে পারে:

def get_var(input_dict, accessor_string):
    """Gets data from a dictionary using a dotted accessor-string"""
    current_data = input_dict
    for chunk in accessor_string.split('.'):
        current_data = current_data.get(chunk, {})
    return current_data

যা এই জাতীয় কিছু সমর্থন করবে:

>> test_dict = {'thing': {'spam': 12, 'foo': {'cheeze': 'bar'}}}
>> output = get_var(test_dict, 'thing.spam.foo.cheeze')
>> print output
'bar'
>>

4

এপুলের উত্তরের ভিত্তিতে এই সংস্করণটি আপনাকে বিন্দু অপারেটরের মাধ্যমে কোনও ডিকের ভিতরে প্রবেশ করতে দেয়:

foo = {
    "bar" : {
        "baz" : [ {"boo" : "hoo"} , {"baba" : "loo"} ]
    }
}

উদাহরণস্বরূপ, foo.bar.baz[1].babaফেরৎ "loo"

class Map(dict):
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    if isinstance(v, dict):
                        v = Map(v)
                    if isinstance(v, list):
                        self.__convert(v)
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                if isinstance(v, dict):
                    v = Map(v)
                elif isinstance(v, list):
                    self.__convert(v)
                self[k] = v

    def __convert(self, v):
        for elem in xrange(0, len(v)):
            if isinstance(v[elem], dict):
                v[elem] = Map(v[elem])
            elif isinstance(v[elem], list):
                self.__convert(v[elem])

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

1
পাইথন 3: এর iteritems()সাথে items()এবং এর xrange()সাথে প্রতিস্থাপন করুনrange()
সাসাভ্যাটক

3
def dict_to_object(dick):
    # http://stackoverflow.com/a/1305663/968442

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

    return Struct(**dick)

যদি কেউ স্থায়ীভাবে রূপান্তর করার সিদ্ধান্ত নেয় তবে তা করা dictউচিত। অ্যাক্সেস করার ঠিক আগে আপনি নিক্ষেপযোগ্য বস্তু তৈরি করতে পারেন।

d = dict_to_object(d)

Def ATTR (** kwargs): ণ = ল্যামডা: কোনটি ণ .__ অভি __ আপডেট করুন (** kwargs) আগমন ণ।
throws_exceptions_at_you

2

আমি এট্র্টিক্ট এবং গুচ্ছ দুটির চেষ্টা করেই শেষ করেছিগ্রন্থাগারগুলি এবং সেগুলিকে আমার ব্যবহারগুলির জন্য ধীর করার উপায় বলে মনে করেছে। একটি বন্ধু এবং আমি এটি সন্ধান করার পরে, আমরা দেখতে পেলাম যে এই লাইব্রেরিগুলি লেখার মূল পদ্ধতিটি গ্রন্থাগারের ফলে আগ্রাসীভাবে কোনও নেস্টেড বস্তুর মাধ্যমে পুনরাবৃত্তি করে এবং অভিধানের সামগ্রীর অনুলিপিগুলি তৈরি করে। এটি মাথায় রেখে আমরা দুটি মূল পরিবর্তন করেছি। 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 দ্বারা দেখুন

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


0

আমি নিজের সমাধানটি রিংয়ের মধ্যে ফেলে দিতে চাই:

https://github.com/skorokithakis/jsane

এটি আপনাকে JSON কে এমন with.attribute.lookups.like.this.r()কোনও কিছুতে পার্স করার অনুমতি দেয় যা আপনি অ্যাক্সেস করতে পারেন , বেশিরভাগ কারণে যে আমি এর উত্তরটি কাজ শুরু করার আগে দেখিনি।


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

0

ওপি-র প্রশ্নের সরাসরি উত্তর নয়, তবে অনুপ্রাণিত হয়ে কারও কারও পক্ষে উপকারী .. আমি অভ্যন্তরীণ ব্যবহার করে একটি অবজেক্ট-ভিত্তিক সমাধান তৈরি করেছি __dict__(কোনওভাবেই অনুকূলিত কোড নয়)

payload = {
    "name": "John",
    "location": {
        "lat": 53.12312312,
        "long": 43.21345112
    },
    "numbers": [
        {
            "role": "home",
            "number": "070-12345678"
        },
        {
            "role": "office",
            "number": "070-12345679"
        }
    ]
}


class Map(object):
    """
    Dot style access to object members, access raw values
    with an underscore e.g.

    class Foo(Map):
        def foo(self):
            return self.get('foo') + 'bar'

    obj = Foo(**{'foo': 'foo'})

    obj.foo => 'foobar'
    obj._foo => 'foo'

    """

    def __init__(self, *args, **kwargs):
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self.__dict__[k] = v
                    self.__dict__['_' + k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self.__dict__[k] = v
                self.__dict__['_' + k] = v

    def __getattribute__(self, attr):
        if hasattr(self, 'get_' + attr):
            return object.__getattribute__(self, 'get_' + attr)()
        else:
            return object.__getattribute__(self, attr)

    def get(self, key):
        try:
            return self.__dict__.get('get_' + key)()
        except (AttributeError, TypeError):
            return self.__dict__.get(key)

    def __repr__(self):
        return u"<{name} object>".format(
            name=self.__class__.__name__
        )


class Number(Map):
    def get_role(self):
        return self.get('role')

    def get_number(self):
        return self.get('number')


class Location(Map):
    def get_latitude(self):
        return self.get('lat') + 1

    def get_longitude(self):
        return self.get('long') + 1


class Item(Map):
    def get_name(self):
        return self.get('name') + " Doe"

    def get_location(self):
        return Location(**self.get('location'))

    def get_numbers(self):
        return [Number(**n) for n in self.get('numbers')]


# Tests

obj = Item({'foo': 'bar'}, **payload)

assert type(obj) == Item
assert obj._name == "John"
assert obj.name == "John Doe"
assert type(obj.location) == Location
assert obj.location._lat == 53.12312312
assert obj.location._long == 43.21345112
assert obj.location.latitude == 54.12312312
assert obj.location.longitude == 44.21345112

for n in obj.numbers:
    assert type(n) == Number
    if n.role == 'home':
        assert n.number == "070-12345678"
    if n.role == 'office':
        assert n.number == "070-12345679"

0

ডট অ্যাক্সেস পাওয়ার একটি সহজ উপায় (তবে অ্যারে অ্যাক্সেস নয়), পাইথনে একটি সরল বস্তু ব্যবহার করা। এটার মত:

class YourObject:
    def __init__(self, *args, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

... এবং এটি এর মতো ব্যবহার করুন:

>>> obj = YourObject(key="value")
>>> print(obj.key)
"value"

... এটিকে ডিকায় রূপান্তর করতে:

>>> print(obj.__dict__)
{"key": "value"}

0

এই সমাধানটি একটি নিয়মিত পদ্ধতিতে নেস্টেড ডিক্টস অ্যাক্সেসের জন্য ওপি প্রয়োজনীয়তার সমাধানের জন্য ইপুল দ্বারা প্রদত্ত একটির পরিশোধন । এপুল দ্বারা সমাধান নেস্টেড ডিক্টস অ্যাক্সেসের অনুমতি দেয় নি।

class YAMLobj(dict):
    def __init__(self, args):
        super(YAMLobj, self).__init__(args)
        if isinstance(args, dict):
            for k, v in args.iteritems():
                if not isinstance(v, dict):
                    self[k] = v
                else:
                    self.__setattr__(k, YAMLobj(v))


    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(YAMLobj, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(YAMLobj, self).__delitem__(key)
        del self.__dict__[key]

এই শ্রেণীর সাথে, এখন ভালো কিছু করতে পারেন: A.B.C.D


0

এটি নেস্টেড ডিক্টসগুলির সাথেও কাজ করে এবং তা নিশ্চিত করে যে পরে যুক্ত করা ডিক্টগুলি একই আচরণ করে:

class DotDict(dict):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Recursively turn nested dicts into DotDicts
        for key, value in self.items():
            if type(value) is dict:
                self[key] = DotDict(value)

    def __setitem__(self, key, item):
        if type(item) is dict:
            item = DotDict(item)
        super().__setitem__(key, item)

    __setattr__ = __setitem__
    __getattr__ = dict.__getitem__

0

@ ডেরেক of৩ এর উত্তরটি খুব ঝরঝরে, তবে এটি তোলা যায় না বা (গভীর) অনুলিপি করা যায় না এবং এটি ফিরে আসেNone হারিয়ে যাওয়া কীগুলির জন্য । নীচের কোডটি এটি ঠিক করে।

সম্পাদনা করুন: আমি উপরের উত্তরটি দেখতে পাই নি যা ঠিক একই পয়েন্টটিকে সম্বোধন করে (upvated)। আমি রেফারেন্সের জন্য উত্তর এখানে রেখে দিচ্ছি।

class dotdict(dict):
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

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

-1

একটি সমাধান ধরনের

class DotDict(dict):

    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

    def __getattr__(self, key):

        def typer(candidate):
            if isinstance(candidate, dict):
                return DotDict(candidate)

            if isinstance(candidate, str):  # iterable but no need to iter
                return candidate

            try:  # other iterable are processed as list
                return [typer(item) for item in candidate]
            except TypeError:
                return candidate

            return candidate

        return typer(dict.get(self, key))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.