Python Class Fields
Question: I am new to Python having come from mainly Java programming.

I am currently pondering over how classes in Python are instantiated.

I understand that `__init__()`: is like the constructor in Java. However,
sometimes python classes do not have an `__init__()` method which in this case
I assume there is a default constructor just like in Java?

Another thing that makes the transition from Java to python slightly difficult
is that in Java you have to define all the class fields with the type and
sometimes an initial value. In python all of this just seems to disappear and
developers can just define new class variables on the fly.

For example I have come across a program like so:

    
    
    class A(Command.UICommand):
        FIELDS = [
            Field( 'runTimeStepSummary', BOOL_TYPE)
            ]
    
        def __init__(self, runTimeStepSummary=False):
            self.runTimeStepSummary = runTimeStepSummary
    
        """Other methods"""
    
        def execute(self, cont, result):
            self.timeStepSummaries = {}
            """ other code"""
    

The thing that confuses (and slightly irritates me) is that this A class does
not have a field called timeStepSummaries yet how can a developer in the
middle of a method just define a new field? or is my understanding incorrect?

So to be clear, my question is in Python can we dynamically define new fields
to a class during runtime like in this example or is this timeStepSummaries
variable an instance of a java like private variable?

EDIT: I am using python 2.7


Answer: > I understand that `__init__()`: is like the constructor in Java.

To be more precise, in Python `__new__` is the constructor method, `__init__`
is the initializer. When you do `SomeClass('foo', bar='baz')`, the
`type.__call__` method basically does:

    
    
    def __call__(cls, *args, **kwargs):
        instance = cls.__new__(*args, **kwargs)
        instance.__init__(*args, **kwargs)
        return instance
    

Generally, most classes will define an `__init__` if necessary, while
`__new__` is more commonly used for immutable objects.

> However, sometimes python classes do not have an **init**() method which in
> this case I assume there is a default constructor just like in Java?

I'm not sure about old-style classes, but this is the case for new-style ones:

    
    
    >>>> object.__init__
    <slot wrapper '__init__' of 'object' objects>
    

If no explicit `__init__` is defined, the default will be called.

> So to be clear, my question is in Python can we dynamically define new
> fields to a class during runtime like in this example

Yes.

    
    
    >>> class A(object):
    ...     def __init__(self):
    ...         self.one_attribute = 'one'
    ...     def add_attr(self):
    ...         self.new_attribute = 'new'
    ...
    
    >>> a = A()
    >>> a.one_attribute
    'one'
    >>> a.new_attribute
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'A' object has no attribute 'new_attribute'
    >>> a.add_attr()
    >>> a.new_attribute
    'new'
    

Attributes can be added to an instance at any time:

    
    
    >>> a.third_attribute = 'three'
    >>> a.third_attribute
    'three'
    

However, it's possible to restrict the instance attributes that can be added
through the class attribute `__slots__`:

    
    
    >>> class B(object):
    ...     __slots__ = ['only_one_attribute']
    ...     def __init__(self):
    ...         self.only_one_attribute = 'one'
    ...     def add_attr(self):
    ...         self.another_attribute = 'two'
    ...
    
    >>> b = B()
    >>> b.add_attr()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 6, in add_attr
    AttributeError: 'B' object has no attribute 'another_attribute'
    

(It's probably important to note that `__slots__` is primarily intended as a
_memory optimization_ \- by not requiring an object have a dictionary for
storing attributes - rather than as a form of run-time modification
prevention.)

