Class Python更新继承的类级字典

Class Python更新继承的类级字典,class,inheritance,dictionary,python-3.x,Class,Inheritance,Dictionary,Python 3.x,我正在寻找一种干净、简单的方法来更新从基类继承的类级词典。例如: class Foo(object): adict = {'a' : 1} class Bar(Foo): adict.update({'b' : 2}) # this errors out since it can't find adict 以便: Foo.adict == {'a' : 1} Bar.adict == {'a' : 1, 'b' : 2} 我不希望在这里使用实例,如果可能的话也不使用类方法

我正在寻找一种干净、简单的方法来更新从基类继承的类级词典。例如:

class Foo(object):
    adict = {'a' : 1}

class Bar(Foo):
    adict.update({'b' : 2})  # this errors out since it can't find adict
以便:

Foo.adict == {'a' : 1}
Bar.adict == {'a' : 1, 'b' : 2}

我不希望在这里使用实例,如果可能的话也不使用类方法。

请注意,即使这样做有效,您也应该更新相同的字典,而不是创建新的字典(因此
Foo.adict是Bar.adict
,因此
Foo.adict==Bar.adict

在任何情况下,最简单的方法是显式引用父类的dict(并复制它,见上文):

我不希望在这里使用实例,如果可能,也不使用类方法

对。所以不要

foo_adict =  {'a' : 1}

def B():
   foo_adict.update({'b': 2})

我不知道为什么要使用类属性级词典,它很少以有用或预期的方式运行。

我也遇到了这个问题。我通过使用元类解决了这个问题,元类也可以用于多重继承:

import six


class CheckerMeta(type):

    def __new__(cls, name, bases, attrs):
        new_class = super(CheckerMeta, cls).__new__(cls, name, bases, attrs)

        base_configs = [bc.config for bc in bases if hasattr(bc, 'config')]
        configs = base_configs + [new_class.config]

        new_class.config = {}
        for config in configs:
            new_class.config.update(config)

        return new_class


class BaseChecker(six.with_metaclass(CheckerMeta)):
    config = {}


class CheckerA(BaseChecker):
    config = {'a': 1}


class CheckerB(BaseChecker):
    config = {'b': 2}


class CheckerC(CheckerA, CheckerB):
    config = {'c': 3}


assert CheckerA.config == {'a': 1}
assert CheckerB.config == {'b': 2}
assert CheckerC.config == {'a': 1, 'b': 2, 'c':3}

Foo
类和
Bar
中初始化
adict
,方法是调用
super
init
进行初始化,然后
update

class Foo(object):
    def __init__(self):
        self.adict = {'a': 1}


class Bar(Foo):
    def __init__(self):
        super(Bar, self).__init__()
        self.adict.update({'b': 2})
例如:

In [14]: b = Bar()
In [15]: b.adict
Out[15]: {'a': 1, 'b': 2}

谢谢-这肯定行得通-我希望我能找到一些更通用的东西(例如,像super),除了继承之外,它不涉及显式引用父类。您在这里并没有使用太多的继承,因为您使用的是类字典。你可以只做一个全球口述。同样的效果。类成员有他们的用途。诚然,它们是高级的,但它们并没有全局的那么差,也不是等价的——每个类可以有单独的值(就像在我的代码片段中一样)。我现在正在研究的代码库在一些地方使用了类成员,尽管不可否认它是用于繁重的元编程的。除了使逻辑分组更加明显外,
classmethod
s还必须从某处获取他们处理的数据。类成员有他们的用途。类成员字典(或其他可变表)通常不会。为了提供一点上下文,我使用这种组织方法来构建API。例如,我希望Foo.adict['a']和Bar.adict['a']能够使用不同的值进行初始化,尽管对于大多数变量,它们是相同的。在类定义之后,将不会修改词典。我还需要Foo和Bar具有静态属性,这些属性不是继承的。我不明白为什么使用类成员词典本身就是一个坏习惯idea@mlauria:“字典在类定义之后不会被修改”-在这种情况下,我再次建议您不要将它们作为类实例。特别是因为它是一个API。对于API的用户来说,这是一个令人困惑的API,他们将开始修改字典,而且它的行为与他们期望的不一样。选项是全局字典,根本没有字典,只有直接的类成员,还有某种只读字典。
In [14]: b = Bar()
In [15]: b.adict
Out[15]: {'a': 1, 'b': 2}