Python - интерактивная оболочка PythonWin вызывает конструкторы дважды?

При ответе Статические переменные класса в 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]
>>>

@Gregory, это больше похоже на отчет об ошибке для PyWin, чем на вопрос SO.

Jason Dagit 17.09.2008 12:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
1
977
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Я предполагаю следующее. Редактор 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. В конечном итоге меня сбивает с толку, когда класс - это одновременно что-то и некая совокупность вещей.

Чем проще, тем лучше, чем сложнее.

Если вы посмотрите на мой пост, я отвечал на прикрепленный статический вопрос. Поэтому я хочу специально изменить переменную класса, а не переменную экземпляра. Написанный мной код - это самый "чистый" способ явного доступа к переменным класса.

Gregory 18.09.2008 02:38

Дэйв Уэбб прав, и вы можете убедиться в этом, добавив оператор печати:

>>> class X:
...     l = []
...     def __init__(self):
...             print 'inited'
...             self.__class__.l.append(1)
...             

Затем, как только вы вводите точку в X()., он печатает inited, прежде чем предлагать вам всплывающее окно завершения.

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