Переменная класса и вопрос переменной экземпляра в Python - PullRequest
3 голосов
/ 18 января 2011

Когда у меня есть этот класс, переменная 'value' является переменной класса.

class Hello:
    value = 10
    def __init__(self):
        print 'init'

У меня есть объект 'h', и я могу получить одинаковое значение '10' как для Hello.value, так и для h.value.

h = Hello()
print Hello.value
print h.value

Когда я запускаю эту команду,

h.value = 20

Я получаю значения '10' и '20', когда запускаю их.

print Hello.value
print h.value

Почему это?

  • В1: Почему «print h.value» печатает значение Hello.value, а не вызывает ошибку?
  • Q2: h.value = 20 вводит новую переменную, похожую на 'self.value = 20'?
  • В3: Есть ли способ предотвратить создание переменной экземпляра (или запретить запуск кода 'h.value = 20')?

Ответы [ 2 ]

4 голосов
/ 18 января 2011

Если Python ищет o.attr, он сначала проверяет экземпляр объекта, затем его класс, затем базовый класс и так далее. Это относится как к методам, так и к атрибутам данных (т. Е. Нет различия между данными и атрибутами кода).

При присваивании значение всегда присваивается экземпляру. Так

  • A1. Потому что это возвращается к класс (который он должен, потому что методы иначе бы не работал)

  • A2. Да, это так.

  • A3. Вы можете определить __setattr__ метод, который вызывает исключение.

4 голосов
/ 18 января 2011

Так работает поиск атрибутов в Python:

  1. Если атрибут не может быть найден в словаре экземпляра, он ищется в словаре своего класса, и, если его там нет, также в словарях базовых классов. .

  2. Если вы назначите атрибут экземпляра, это всегда будет влиять только на экземпляр - то есть обновлять атрибут, если он уже существует в экземпляре, или создавать его в словаре экземпляра, если нет.

Если вам не нравится это поведение, вы можете перезаписать метод __setattr__(), чтобы сделать что угодно - например, выдать ошибку, если вы не хотите разрешать создание атрибутов экземпляра. Последнее также может быть достигнуто путем добавления __slots__ = [] к классу.

...