通过类属性访问字典

4 投票
6 回答
3086 浏览
提问于 2025-04-15 13:54

我现在在用Python,遇到一个关于字典的问题……

假设我有一个字典,内容是这样的:

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,这样也能返回对应的值。

我该怎么实现这个呢?

6 个回答

3

你需要使用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
7

你可以使用collections.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

13

为了这个目的,很多年前我发明了一个简单的 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 中设置或删除项目也会自动在实例中设置或删除相应的属性。

撰写回答