Extensible Dictionary with Class Attribute

I am working with python now. So, one question about dict .... suppose I have a dict that

config = {'account_receivable': '4', 'account_payable': '5', 'account_cogs': '8', 'accoun t_retained_earning': '9', 'account_income': '6', 'account_expense': '31', 'durat ion': 2, 'financial_year_month': 9, 'financial_year_day': 15, 'account_cash': '3 ', 'account_inventory': '2', 'account_accumulated_depriciation': '34', 'account_ depriciation_expense': '35', 'account_salary_expense': '30', 'account_payroll_pa yable': '68', 'account_discount': '36', 'financial_year_close': '2008-08-08'} 

if print β†’ config ['account_receivable'], it will return the corresponding value, which is 4

but I want to access it this way -> config.account_receivable, and then it will return the corresponding value to it

how can i implement this ??? if anyone can help me

BR // nazmul

+4
source share
6 answers

For this purpose, many years ago, I came up with the simple idiom Bunch ; One easy way to implement Bunch :

 class Bunch(object): def __init__(self, adict): self.__dict__.update(adict) 

If config is a dict, you cannot use config.account_receivable - it is absolutely impossible because dict does not have this attribute, period. However, you can wrap config in Bunch :

 cb = Bunch(config) 

and then access cb.config_account on your heart content!

Edit : if you want the assignment of attributes to Bunch also affect the original dict ( config in this case) so that, for example, cb.foo = 23 will execute config['foo'] = 23 , you will need a small implementation of Bunch :

 class RwBunch(object): def __init__(self, adict): self.__dict__ = adict 

Usually a regular Bunch is preferred, precisely because after creating the instance of Bunch and dict it was β€œprimed” from completely untied ones - changes in any of them do not affect the others; and such a denouement is usually desired.

When you want communication effects, then RwBunch is the way to get them: with it, each parameter or deleting an attribute in an instance will internally set or remove an element from a dict , and, conversely, setting or deleting elements from a dict will internally set or remove attributes from an instance .

+12
source

You can do this with collection.namedtuple:

 from collections import namedtuple config_object = namedtuple('ConfigClass', config.keys())(*config.values()) print config_object.account_receivable 

You can learn more about namedtuple here:

http://docs.python.org/dev/library/collections.html

+7
source

You need to use one of the special Python methods .

 class config(object): def __init__(self, data): self.data = data def __getattr__(self, name): return self.data[name] c = config(data_dict) print c.account_discount -> 36 
+2
source

Well, you could do this with a bunch of objects.

 class Config(object): pass config = Config() config.account_receivable = 4 print config.account_receivable 

Obviously, you can extend this class to do more for you. e.g. define __init__ so that you can create it with arguments and possibly by default.

You can also use namedtuple ( python 2.4 / 2.5) . This is a data structure specifically designed to store structured records.

 from collections import namedtuple Config = namedtuple('Config', 'account_receivable account_payable') # etc -- list all the fields c = Config(account_receivable='4', account_payable='5') print c.account_receivable 

With namedtuples, you cannot change values ​​after setting them.

0
source

You can subclass dict to return elements from yourself for undefined attributes:

 class AttrAccessibleDict(dict): def __getattr__(self, key): try: return self[key] except KeyError: return AttributeError(key) config = AttrAccessibleDict(config) print(config.account_receivable) 

You can also override some other methods, such as __setattr__ , __delattr__ , __str__ , __repr__ and copy .

0
source

All Articles