类中的嵌套字典

时间:2015-10-21 19:07:14

标签: python dictionary

我遇到了这种数据结构的意外行为。

    class IncomeVerification(object):

        data = {'IncomeYears': []}

        def __init__(self, income_years):
            for year in income_years:
                new_year = IncomeYear(year).data
                self.data['IncomeYears'].append(new_year)

    class IncomeYear(object):
        data = {'IncomeYear': {'Year': None}}

        def __init__(self, year, reported_income=None):
            self.data['IncomeYear']['Year'] = year

    income_years = ['2014', '2013', '2012', '2011']

    foo = IncomeVerification(income_years)
    print foo.data

返回

     {'IncomeYears': [{'IncomeYear': {'Year': '2011'}}, {'IncomeYear': {'Year': '2011'}}, {'IncomeYear': {'Year': '2011'}}, {'IncomeYear': {'Year': '2011'}}]}

我期待,

    {'IncomeYears': [{'IncomeYear': {'Year': '2014'}}, {'IncomeYear': {'Year': '2013'}}, {'IncomeYear': {'Year': '2012'}}, {'IncomeYear': {'Year': '2011'}}]}

我相信我的词典的嵌套特性会产生独特的关键问题,因此会覆盖现有的条目。关于如何修改上述调用以获得我想要的结果的任何想法?

谢谢。

2 个答案:

答案 0 :(得分:2)

您在自己的代码中反复添加引用而不是新的dict/objectself.data['IncomeYears'].append(new_year),因此每当您进行更改时,您实际上都在更改同一个对象。

您需要使用自己的代码deepcopy数据:

from copy import deepcopy
class IncomeVerification(object):

        data = {'IncomeYears': []}
        def __init__(self, income_years):
            for year in income_years:
                new_year = deepcopy(IncomeYear(year).data)

哪个会输出:

{'IncomeYears': [{'IncomeYear': {'Year': '2014'}}, {'IncomeYear': {'Year': '2013'}}, {'IncomeYear': {'Year': '2012'}}, {'IncomeYear': {'Year': '2011'}}]}

或者更好地再次在data中使IncomeYear成为实例属性,而不是当前创建一次并在所有实例之间共享的类属性:

class IncomeVerification(object):
        data = {'IncomeYears': []}
        def __init__(self, income_years):
            for year in income_years:
                new_year = IncomeYear(year).data
                self.data['IncomeYears'].append(new_year)

class IncomeYear(object):
    def __init__(self, year, reported_income=None):
        # new dict/object for each instance
        self.data = {'IncomeYear': {'Year': None}}
        self.data['IncomeYear']['Year'] = year

income_years = ['2014', '2013', '2012', '2011']

foo = IncomeVerification(income_years)
print(foo.data)

再次输出:

{'IncomeYears': [{'IncomeYear': {'Year': '2014'}}, {'IncomeYear': {'Year': '2013'}}, {'IncomeYear': {'Year': '2012'}}, {'IncomeYear': {'Year': '2011'}}]}

class vs instance attributes

答案 1 :(得分:1)

这是因为类中的data属性是类变量,其行为类似于其他编程语言的静态属性,因为它们对于类是唯一的,而不是每个它的实例。

要让您的代码正常工作,您必须将它们移到__init__()方法中,使其成为实例变量,如下所示:

class IncomeVerification(object):

    def __init__(self, income_years):
        self.data = {'IncomeYears': []}
        for year in income_years:
            new_year = IncomeYear(year).data
            self.data['IncomeYears'].append(new_year)

class IncomeYear(object):

    def __init__(self, year, reported_income=None):
        self.data = {'IncomeYear': {'Year': None}}
        self.data['IncomeYear']['Year'] = year

income_years = ['2014', '2013', '2012', '2011']

foo = IncomeVerification(income_years)
print  foo.data

运行它会返回:

{'IncomeYears': [{'IncomeYear': {'Year': '2014'}}, {'IncomeYear': {'Year': '2013'}}, {'IncomeYear': {'Year': '2012'}}, {'IncomeYear': {'Year': '2011'}}]}

如你所料。