Вопрос, связанный с классом нового стиля Python

Я изучаю Python и в настоящее время взламываю класс с переменным количеством полей, как в Пример "Bunch of Named Stuff" здесь.

class Bunch:
    def __init__(self, **kwds):
        self.__dict__.update(kwds)

Я также хочу написать __setattr__ в этом классе, чтобы проверить имя входного атрибута. Но в документации Python говорится:

Если __setattr__() хочет присвоить значение атрибуту экземпляра, она не должна просто выполнять «self.name = value» — это вызовет рекурсивный вызов самого себя. Вместо этого он должен вставить значение в словарь атрибутов экземпляра, например, «self.__dict__[имя] = значение». Для классов нового стиля вместо доступа к словарю экземпляра следует вызывать метод базового класса с тем же именем, например, «object.__setattr__(self, name, value)».

В таком случае, должен ли я также использовать object.__dict__ в функции __init__ для замены self.__dict__?


person amit    schedule 10.06.2011    source источник


Ответы (2)


Нет. Вы должны определить свой класс как class Bunch(object), но продолжать ссылаться на self.__dict__.

Вам нужно использовать только метод object.__setattr__, когда вы определяете метод self.__setattr__, чтобы предотвратить бесконечную рекурсию. __dict__ — это не метод, а атрибут самого объекта, поэтому object.__dict__ работать не будет.

person Jeremy    schedule 10.06.2011
comment
Часть о object.__dict__ более или менее ясна. Однако причина использования baseclass.__setattr__, по-видимому, заключается в вызове пользовательской перегрузки в базовом классе. Я прав? - person amit; 10.06.2011
comment
Я бы не сказал, что вы вызываете пользовательский в базовом классе. Поскольку вы переопределяете способ обновления атрибутов пользовательским методом перегрузки, вы не можете использовать этот метод внутри себя. Поскольку вы пытаетесь обновить атрибут без использования нового пользовательского механизма, вместо этого вы ссылаетесь на него из базового класса. - person Jeremy; 10.06.2011

Ты можешь использовать

class Bunch:
    def __init__(self, **kwds):
        self.__dict__.update(kwds)

    def __setattr__(self, name, value):
        #do your verification stuff
        self.__dict__[name] = value

или с классом нового стиля:

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

    def __setattr__(self, name, value):
        #do your verification stuff
        super(Bunch, self).__setattr__(name, value)
person Cédric Julien    schedule 10.06.2011