Доступ к словарю с атрибутом класса - PullRequest
4 голосов
/ 27 августа 2009

сейчас я работаю с питоном. Так что один вопрос про диктовку .... Предположим, у меня есть диктат, что

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'}

если print -> config ['account_receivable'], он вернёт соответствующее ему значение 4

но я хочу получить к нему доступ таким образом -> config.account_receivable, а затем он вернет ему соответствующее значение

как я могу это реализовать ??? если кто-нибудь может помочь мне

BR // nazmul

Ответы [ 6 ]

12 голосов
/ 27 августа 2009

Для этой цели много лет назад я изобрел простую идиому Bunch; Один простой способ реализовать Bunch это:

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

Если config является диктом, вы не можете использовать config.account_receivable - это абсолютно невозможно, потому что у диктанта нет этого атрибута, точка. Тем не менее, вы можете обернуть config в Bunch:

cb = Bunch(config)

, а затем получите доступ к cb.config_account к своему сердцу!

Редактировать : если вы хотите, чтобы присвоение атрибута на Bunch также влияло на оригинал dict (config в данном случае), например, например. cb.foo = 23 сделает config['foo'] = 23, вам нужна немного другая реализация Bunch:

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

Обычно предпочитается простой Bunch, в точности , потому что , после создания экземпляра, экземпляр Bunch и dict, из которого он был «заполнен», полностью отделены - изменяется на любой из они не влияют на других; и такое разделение, чаще всего, и является желательным.

Когда вы делаете хотите «связать» эффекты, тогда RwBunch - это способ их получить: с его помощью каждый параметр или удаление атрибута по своей сути будет устанавливать или удалять элемент из dict, и, наоборот, установка или удаление элементов из dict по своей природе устанавливает или удаляет атрибуты из экземпляра.

7 голосов
/ 27 августа 2009

Вы можете сделать это с collection.namedtuple:

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

Подробнее о namedtuple можно узнать здесь:

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

3 голосов
/ 27 августа 2009
2 голосов
/ 27 августа 2009

Вам необходимо использовать один из специальных методов Python .

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
0 голосов
/ 27 августа 2009

Вы можете подкласс dict возвращать элементы из себя для неопределенных атрибутов:

class AttrAccessibleDict(dict):
    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:    
            return AttributeError(key)

config = AttrAccessibleDict(config)
print(config.account_receivable)

Вы также можете переопределить некоторые другие методы, такие как __setattr__, __delattr__, __str__, __repr__ и copy.

0 голосов
/ 27 августа 2009

Ну, вы могли бы сделать это с кучей объектов.

class Config(object):
    pass

config = Config()
config.account_receivable = 4
print config.account_receivable

Очевидно, вы можете расширить этот класс, чтобы сделать больше для вас. например определите __init__, чтобы вы могли создать его с аргументами и, возможно, по умолчанию.

Можно также использовать namedtuple ( python 2.4 / 2.5 link ). Это структура данных, специально предназначенная для хранения структурированных записей.

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

С именованными кортами вы не можете изменять значения после их установки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...