Python обновление унаследованного словаря уровня класса - PullRequest
5 голосов
/ 27 декабря 2011

Я ищу простой и простой способ обновления словарей уровня класса, которые унаследованы от базовых классов.Например:

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}

Я бы предпочел не использовать здесь экземпляры и, если возможно, не использовать методы класса.

Ответы [ 4 ]

5 голосов
/ 27 декабря 2011

Обратите внимание, что даже если бы это сработало, вы бы обновили один и тот же словарь вместо создания нового (поэтому Foo.adict is Bar.adict и, следовательно, Foo.adict == Bar.adict).

В любом случае, самый простой способявным образом обратитесь к диктанту родительского класса (и скопируйте его, см. выше):

class Bar(Foo):
    adict = dict(Foo.adict)
    adict.update({'b': 2})
1 голос
/ 04 февраля 2017

Я тоже встречался с этой проблемой.Я решил это с помощью метакласса, который также может работать с множественным наследованием:

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}
0 голосов
/ 14 июня 2017

Инициализируйте adict в Foo классе и Bar инициализируйте, вызвав init из super затем 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}
0 голосов
/ 28 декабря 2011

"Я бы предпочел не использовать здесь экземпляры и, если возможно, не использовать методы класса."

Верно.Так что не надо.

foo_adict =  {'a' : 1}

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

Я не уверен, почему вы используете словари уровня атрибутов класса, он редко ведет себя полезным или ожидаемым образом.

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