Вопрос переменной класса и переменной экземпляра в Python
-
12-10-2019 - |
Вопрос
Когда у меня есть этот класс, переменная «значение» является переменной класса.
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
Почему это?
- Q1: Почему «print h.value» распечатывает значение hello.value, а не выносите ошибку?
- Q2: H.Value = 20 представляет новую переменную, похожую на 'self.value = 20'?
- Q3: Есть ли способ предотвратить создание переменной экземпляра (или предотвратить запуск кода 'h.value = 20')?
Решение
Вот как работает поиск атрибутов в Python:
Если атрибут не может быть найден в словаре экземпляра, он смотрит в словаре своего класса, и если его нельзя найти, также в словари базовых классов.
Если вы назначаете атрибут экземпляра, это всегда повлияет на экземпляр - IE обновите атрибут, если он уже существует в экземпляре или создаст его в словаре экземпляра, если нет.
Если вам не нравится это поведение, вы можете перезаписать __setattr__()
Метод для того, чтобы делать все, что вам нравится - например, выбросить ошибку, если вы не хотите разрешать создание атрибутов экземпляра. Последний также может быть достигнут путем добавления __slots__ = []
к классу.
Другие советы
Если Python смотрит o.attr
, сначала проверяет экземпляр объекта, затем его класс, затем базовый класс и так далее. Это происходит как для методов, так и для атрибутов данных (то есть нет различий между данными и атрибутами кода).
При назначении значение всегда назначается экземпляру. Так
A1. Потому что он возвращается к классу (что должно быть, потому что методы не будут работать иначе)
A2. Да, это так.
A3. Вы можете определить
__setattr__
Метод, который поднимает исключение.