Вопрос переменной класса и переменной экземпляра в Python

StackOverflow https://stackoverflow.com/questions/4718801

Вопрос

Когда у меня есть этот класс, переменная «значение» является переменной класса.

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:

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

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

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

Другие советы

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top