PythonWin's python interactive shell calling constructors twice?

While answering Static class variables in Python

I noticed that PythonWin PyWin32 build 209.2 interpreter seems to evaluate twice?

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]

while the python interpreter does the right thing

ActivePython (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

Asked by: Kristian861 | Posted: 05-10-2021

Answer 1

My guess is as follows. The PythonWin editor offers autocomplete for an object, i.e. when you type myobject. it offers a little popup of all the availble method names. So I think when you type X(). it's creating an instance of X in the background and doing a dir or similar to find out the attributes of the object.

So the constructor is only being run once for each object but to give you the interactivity it's creating objects silently in the background without telling you about it.

Answered by: John889 | Posted: 06-11-2021

Answer 2

Dave Webb is correct, and you can see this by adding a print statement:

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

Then as soon as you type the period in X(). it prints inited prior to offering you the completion popup.

Answered by: Michael260 | Posted: 06-11-2021

Answer 3

Two small additional points.

First, self.__class__.l.append(1) isn't really sensible.

Just say self.l.append(1). Python searches the instance before it searches the class for the reference.

More importantly, class-level variables are rarely useful. Class-level constants are sometimes sensible, but even then, they're hard to justify.

In C++ and Java, class-level ('static') variables seem handy, but don't do much of value. They're hard to teach to n00bz -- often wasting lots of classroom time on minutia -- and they aren't very practical. If you want to know all instances of an X that was created, it's probably better to create an XFactory class that doesn't rely on class variables.

class XFactory( object ):
    def __init__( self ):
        self.listOfX= []
    def makeX( self, *args, **kw ):
        newX= X(*args,**kw)
        return newX

No class-level variable anomalies. And, it doesn't conflate the X's with the collection of X's. In the long run, I find it confusing when a class is both some thing and also some collection of things.

Simpler is better than Complex.

Answered by: Emily106 | Posted: 06-11-2021

Similar questions

exception - Python: Problem with overloaded constructors

WARNING: I have been learning Python for all of 10 minutes so apologies for any stupid questions! I have written the following code, however I get the following exception: Message File Name Line Position Traceback Node 31 exceptions.TypeError: this constructor takes no arguments class Computer: name = "Computer...

How to handle constructors or methods with a different set (or type) of arguments in Python?

Is there a way in Python, to have more than one constructor or more than one method with the same name, who differ in the number of arguments they accept or the type(s) of one or more argument(s)? If not, what would be the best way to handle such situations? For an example I made up a color class. This class should only work as a basic example to discuss this, there is lo...

python - What is a clean "pythonic" way to implement multiple constructors?

I can't find a definitive answer for this. As far as I know, you can't have multiple __init__ functions in a Python class. So how do I solve this problem? Suppose I have a class called Cheese with the number_of_holes property. How can I have two ways of creating cheese objects... One that takes a number of holes like this: parmesan = Cheese(num_holes = 15)

Constructors in Python

How do derived class constructors work in python?

I have the following base class: class NeuralNetworkBase: def __init__(self, numberOfInputs, numberOfHiddenNeurons, numberOfOutputs): self.inputLayer = numpy.zeros(shape = (numberOfInputs)) self.hiddenLayer = numpy.zeros(shape = (numberOfHiddenNeurons)) self.outputLayer = numpy.zeros(shape = (numberOfOutputs)) self.hiddenLayerWeights = numpy.zeros(shape = (numberOfInputs...

Is it not possible to define multiple constructors in Python?

This question already has answers here:

python - Multiple inheritance in django. Problem with constructors

I have a model like this: class Person(models.Model,Subject): name = .. The class Subject is not supposed to be in the Database so, it doesn't extends from models.Model: class Subject: def __init__(self,**kargs): _observers = [] my problem is that the constructor of Subject is never called, so i've tried adding this to the ...

Differences Between Python and C++ Constructors

I've been learning more about Python recently, and as I was going through the excellent Dive into Python the author noted here that the __init__ method is not technically a constructor, even though it generally functions like one. I have two questions:

python - lxml objectify does not call constructors for custom element classes

lxml.objectify does not seem to call the constructors for my custom element classes: from lxml import objectify, etree class CustomLookup(etree.CustomElementClassLookup): def lookup(self, node_type, document, namespace, name): lookupmap = { 'custom' : CustomElement } try: return lookupmap[name] except KeyError: return None class CustomElement(etree.Eleme...

python - How to mock objects with constructors in Python3?

I'm new to Python (I'm from Java) and I'm facing an issue in using mocks in Python3.2. Here is the code: import gzip class MyClass: _content = None _gzipfile = gzip.GzipFile def __init__(self, content): self._content = content def my_method(self): # Code ... gzipper = self._gzipfile(fileobj=data) return import unittest from mo...

Still can't find your answer? Check out these communities...

PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python