views:

128

answers:

6

Hi all,

now i am working with python. 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 its corresponding value that 4

but i want to access it by that way--> config.account_receivable and then it will return it corresponding value

how i can implement this??? if any one can please help me

BR// nazmul

A: 

Well, you could do it 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 you can create it with arguments, and perhaps defaults.

You could possibly also use a namedtuple (python 2.4/2.5 link). This is a data structure specifically designed to hold 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 once they have been set.

John Fouhy
+2  A: 

You need to use one of Python's special 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
gahooa
thank you very much
nazmul hasan
+6  A: 

You can do this with collections.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

samtregar
+10  A: 

For that purpose, lo that many years ago, I invented the simple Bunch idiom; one simple way to implement Bunch is:

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

If config is a dict, you can't use config.account_receivable -- that's absolutely impossible, because a dict doesn't have that attribute, period. However, you can wrap config into a Bunch:

cb = Bunch(config)

and then access cb.config_account to your heart's content!

Edit: if you want attribute assignment on the Bunch to also affect the original dict (config in this case), so that e.g. cb.foo = 23 will do config['foo'] = 23, you need a slighly different implementation of Bunch:

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

Normally, the plain Bunch is preferred, exactly because, after instantiation, the Bunch instance and the dict it was "primed" from are entirely decoupled -- changes to either of them do not affect the other; and such decoupling, most often, is what's desired.

When you do want "coupling" effects, then RwBunch is the way to get them: with it, every attribute setting or deletion on the instance will intrinsically set or delete the item from the dict, and, vice versa, setting or deleting items from the dict will intrinsically set or delete attributes from the instance.

Alex Martelli
A: 

You can subclass dict to return items from itself 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 might also want to override some other methods as well, such as __setattr__, __delattr__, __str__, __repr__ and copy.

Ants Aasma