Помните, что оператор class
в Python намного ближе к любому другому оператору блока, чем в случае языков, подобных C ++.
В Python оператор class
содержит нескольковыполняемые операторы, такие как def
, if
или while
.Разница только в том, что интерпретатор делает с блоком.В случае операторов блока управления потоком, таких как if
и while
, интерпретатор выполняет блок в соответствии со значением оператора управления потоком.В def
интерпретатор сохраняет блок и выполняет его всякий раз, когда вызывается объект функции.
В случае блока class
Python выполняет блок немедленно , вновая область, а затем использует все, что осталось в этой области после завершения выполнения, как содержимое класса.
Итак, для этого:
class testa():
a = []
Python выполняет блок a = []
.Затем в конце область действия содержит a
, привязанную к пустому объекту списка.Так вот что у вас в классе .Это не какой-то конкретный экземпляр класса, а сам класс.
Он наследует конструктор бездействия от object
, поэтому при создании экземпляра класса с помощью ta1 = testa()
вы получите пустой экземпляр.Затем, когда вы запрашиваете ta1.a
, Python не находит переменную экземпляра с именем a
(потому что ta1
вообще не имеет переменных экземпляра), и поэтому он ищет a
в классе testa
.Это, конечно, он находит;но он находит один и тот же для каждого экземпляра testa
, и поэтому вы получаете поведение, которое вы наблюдали.
С другой стороны, это:
class testb():
def __init__(self):
self.a = []
полностью отличается.Здесь после того, как блок класса был выполнен, содержимое области видимости снова представляет собой одно имя, но на этот раз оно __init__
связано с функцией.Это становится содержанием класса.
Теперь, когда вы создаете экземпляр этого класса с помощью testb()
, Python находит __init__
в классе и вызывает эту функцию с новым экземпляром.При выполнении этой функции в новом экземпляре создается переменная a
instance .Таким образом, каждый экземпляр testb()
получает свою собственную переменную, и вы наблюдаете поведение.
Возьмите домашнее сообщение: блок class
в Python - это , а не просто набор объявленийвещи, которые содержатся в экземплярах этого класса, в отличие от традиционных языков программирования, таких как C ++ и Java.Это фактический код, который фактически выполняется для определения содержимого класса.Это может быть очень удобно: вы можете использовать операторы if, результаты выполнения функций и все, что вы будете использовать в любом другом контексте, внутри тела класса, чтобы решить, что определить в вашем классе.
( NOTE : Раньше я лгал для простоты. Даже экземпляры testa
будут иметь некоторые переменные экземпляра, потому что есть некоторые, которые автоматически создаются по умолчанию для всех экземпляров, но вы не видите их так часто в течение дня.современный Python).