PythonWin - это интерактивная оболочка Python, вызывающая конструкторов дважды? - PullRequest
2 голосов
/ 17 сентября 2008

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

Ответы [ 3 ]

3 голосов
/ 17 сентября 2008

Мое предположение следующее. Редактор PythonWin предлагает автозаполнение для объекта, т.е. когда вы набираете myobject., он предлагает небольшое всплывающее окно со всеми доступными именами методов. Поэтому я думаю, что когда вы набираете X()., он создает экземпляр X в фоновом режиме и выполняет dir или подобное, чтобы выяснить атрибуты объекта.

Таким образом, конструктор запускается только один раз для каждого объекта , но для обеспечения интерактивности он создает объекты в фоновом режиме, не сообщая вам об этом.

2 голосов
/ 17 сентября 2008

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

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

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

1 голос
/ 17 сентября 2008

Два небольших дополнительных очка.

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

Проще лучше, чем Комплекс.

...