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 __ini
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__
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 "", line 1, in
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 "", line 1, in
File "", 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.)