класс, dict, self, init, args? - PullRequest
       10

класс, dict, self, init, args?

11 голосов
/ 15 апреля 2010
class attrdict(dict):
    def __init__(self, *args, **kwargs):
        dict.__init__(self, *args, **kwargs)
        self.__dict__ = self

a = attrdict(x=1, y=2)
print a.x, a.y

b = attrdict()
b.x, b.y  = 1, 2
print b.x, b.y

Может ли кто-нибудь объяснить первые четыре строки словами? Я читал о классах и методах. Но здесь это кажется очень запутанным.

Ответы [ 3 ]

7 голосов
/ 15 апреля 2010

Мой взгляд на построчное объяснение:

class attrdict(dict):

Эта строка объявляет атрибут класса как подкласс встроенного класса dict.

def __init__(self, *args, **kwargs): 
    dict.__init__(self, *args, **kwargs)

Это ваш стандартный __init__ метод. Призыв к dict.__init__(...) заключается в использовании супер Метод конструктора класса (в данном случае dict) (__init__).

Последняя строка, self.__dict__ = self, делает так, чтобы ключевые слова-аргументы (kwargs), которые вы передаете методу __init__, были доступны как атрибуты, т.е.

Надеюсь, это поможет прояснить ваше замешательство.

5 голосов
/ 15 апреля 2010

Вы не используете позиционные аргументы в вашем примере. Так что соответствующий код:

class attrdict(dict):
    def __init__(self, **kwargs):
        dict.__init__(self, **kwargs)
        self.__dict__ = self

В первой строке вы определяете класс attrdict как подкласс dict. Во второй строке вы определяете функцию, которая автоматически инициализирует ваш экземпляр. Вы передаете аргументы ключевого слова (**kargs) этой функции. Когда вы создаете экземпляр a:

 a = attrdict(x=1, y=2)

Вы на самом деле звоните

attrdict.__init__(a, {'x':1, 'y':2})

инициализация ядра экземпляра dict выполняется путем инициализации встроенного суперкласса dict. Это делается в третьей строке, передавая параметры, полученные в attrdict.__init__. Таким образом,

dict.__init__(self,{'x':1, 'y':2})

делает self (экземпляр a) словарем:

self ==  {'x':1, 'y':2}

Самое приятное происходит в последней строке: У каждого экземпляра есть словарь, содержащий его атрибуты. Это self.__dict__ (т.е. a.__dict__).

Например, если

a.__dict__ = {'x':1, 'y':2} 

мы могли бы написать a.x или a.y и получить значения 1 или 2 соответственно.

Итак, вот что делает строка 4:

self.__dict__ = self

эквивалентно:

a.__dict__ = a  where a = {'x':1, 'y':2}

Тогда я могу позвонить a.x и a.y.

Надеюсь, что не слишком грязно.

4 голосов
/ 15 апреля 2010

Вот хорошая статья, которая объясняет __dict__:

Динамический дикт

Класс attrdict использует это, наследуя от словаря, а затем устанавливая __dict__ объекта в этот словарь. Таким образом, любой доступ к атрибуту происходит по отношению к родительскому словарю (то есть классу dict, от которого он наследуется).

Остальная часть статьи также хороша для понимания объектов Python:

Атрибуты и методы Python

...