При ответе Статические переменные класса в Python
Я заметил, что интерпретатор PythonWin PyWin32 build 209.2, кажется, оценивает дважды?
PythonWin 2.5 (r25:51908, Mar 9 2007, 17:40:28) [MSC v.1310 32 bit (Intel)] on win32.
Portions Copyright 1994-2006 Mark Hammond - see 'Help/About PythonWin' for further copyright information.
>>> class X:
... l = []
... def __init__(self):
... self.__class__.l.append(1)
...
>>> X().l
[1, 1]
>>>
в то время как интерпретатор python делает правильные вещи
C:\>python
ActivePython 2.5.0.0 (ActiveState Software Inc.) based on
Python 2.5 (r25:51908, Mar 9 2007, 17:40:28) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class X:
... l = []
... def __init__(self):
... self.__class__.l.append(1)
...
>>> X().l
[1]
>>>






Я предполагаю следующее. Редактор PythonWin предлагает автозаполнение для объекта, т.е. когда вы вводите myobject., он предлагает небольшое всплывающее окно со всеми доступными именами методов. Поэтому я думаю, что когда вы вводите X()., он создает экземпляр X в фоновом режиме и выполняет dir или что-то подобное, чтобы узнать атрибуты объекта.
Таким образом, конструктор запускается только один раз для каждого объекта, но для обеспечения интерактивности он создает объекты в фоновом режиме, не сообщая вам об этом.
Два небольших дополнительных пункта.
Во-первых, self.__class__.l.append(1) не очень разумный.
Просто скажите self.l.append(1). Python ищет экземпляр, прежде чем искать ссылку в классе.
Что еще более важно, переменные уровня класса редко бывают полезными. Константы уровня класса иногда разумны, но даже в этом случае их трудно оправдать.
В C++ и Java переменные уровня класса (static) кажутся удобными, но не имеют особого значения. Их трудно научить n00bz - часто они тратят много времени в классе на мелочи - и они не очень практичны. Если вы хотите знать все экземпляры X, которые были созданы, вероятно, лучше создать класс XFactory, который не полагается на переменные класса.
class XFactory( object ):
def __init__( self ):
self.listOfX= []
def makeX( self, *args, **kw ):
newX= X(*args,**kw)
self.listOfX.append(newX)
return newX
Нет аномалий переменных на уровне класса. И это не объединяет X с набором X. В конечном итоге меня сбивает с толку, когда класс - это одновременно что-то и некая совокупность вещей.
Чем проще, тем лучше, чем сложнее.
Если вы посмотрите на мой пост, я отвечал на прикрепленный статический вопрос. Поэтому я хочу специально изменить переменную класса, а не переменную экземпляра. Написанный мной код - это самый "чистый" способ явного доступа к переменным класса.
Дэйв Уэбб прав, и вы можете убедиться в этом, добавив оператор печати:
>>> class X:
... l = []
... def __init__(self):
... print 'inited'
... self.__class__.l.append(1)
...
Затем, как только вы вводите точку в X()., он печатает inited, прежде чем предлагать вам всплывающее окно завершения.
@Gregory, это больше похоже на отчет об ошибке для PyWin, чем на вопрос SO.