2013-08-14 3 views
0

я после двух образцов кодаPython: Поведение переменных класса и экземпляра

Пример 1:

class MyClass(object): 

    def __init__(self, key, value): 
     self._dict = self._dict.update({key:value}) 

m = MyClass('ten',10) 
print m._dict 

Выход:

AttributeError: 'MyClass' object has no attribute '_dict' 

Пример2:

class MyClass(object): 
    _dict = {} 
    def __init__(self, key, value): 
     self._dict = self._dict.update({key:value}) 

m = MyClass('ten',10) 
print m._dict 

Выходной : None

Я очень удивлен поведением выше

Почему example2 успешно составленный только добавлением _dict = {} линия и линия настоящего в области видимости класса. тоже почему None мощность? Я полагал, что переменные класса класса не имеют отношения к переменной экземпляра (special with self)

Любое объяснение?

ответ

1

None выход - это потому, что dict.update не возвращается. Он сам модифицирует словарь, но ничего не возвращает. Так что вы, вероятно, хотели self._dict.update({key:value}). Однако при инициализации self._dict не существует. Поэтому было бы целесообразнее сделать self._dict = {key: value}. Если вы пытаетесь изменить внутренний словарь объекта, тогда вы должны сделать self.__dict__.update({key:value}). Однако это плохая практика. Лучшей идеей было бы написать setattr(self, key, value). Причина Example2 работает успешно, потому что если вы попытаетесь сделать getattr(instance, thing) (что и есть instance.thing), а thing не находится в instance.__dict__, тогда вместо этого будет проверен instance.__class__.__dict__.

0

self._dict еще не существует, поэтому первая версия повышает это исключение. Второй фактически проваливается через объект _dict в экземпляр и вместо этого обновляет атрибут класса, а затем присваивает словарь уровня класса атрибуту scope-scope _dict.

2

Ваш «пример 2» определяет один словарь на уровне класса. Все экземпляры класса будут использовать тот же словарь, по крайней мере, если вы не переназначаете _dict для экземпляра.

Смотрите этот вопрос для подробного объяснения: Why do attribute references act like this with Python inheritance?

А почему вы получаете None - метод update меняет Dict на месте, и возвращает None.

1

Поскольку _dict в примере 2 является переменной класса, поэтому он является атрибутом MyClass, где в качестве примера в примере 1 указан экземпляр переменной, поэтому это атрибут экземпляра.

1

Пример 1: вы пытаетесь обновить объект, который еще не создан. поэтому погрешность.

Пример 2: При работе во внутренней области функции, если вы изменяете переменную, она вносит изменения в ранее определенный _dict.Но если вы назначаете значение, он создает новую переменную с тем же именем во внутренней области.

Это будет работать.

class MyClass(object): 
    _dict = {} 
    def __init__(self, key, value): 
     self._dict.update({key:value}) 

Это не будет.

class MyClass(object): 
    _dict = {} 
    def __init__(self, key, value): 
     self._dict = self._dict.update({key:value}) 

потому что вы выполняете операцию присваивания. Он создает новую переменную. Таким образом, никаких изменений в _dict во внешней области не происходит. Ваш _dict во внешней области по-прежнему пуст и возвращает None.

Смежные вопросы