When feasible, letting __init__ get called (and make the call innocuous by suitable arguments) is preferable. However, should that require too much of a contortion, you do have an alternative, as long as you avoid the disastrous choice of using old-style classes (there is no good reason to use old-style classes in new code, and several good reasons not to)...:

   class String(object):
      ...

   bare_s = String.__new__(String)

This idiom is generally used in classmethods which are meant to work as "alternative constructors", so you'll usually see it used in ways such as...:

@classmethod 
def makeit(cls):
    self = cls.__new__(cls)
    # etc etc, then
    return self

(this way the classmethod will properly be inherited and generate subclass instances when called on a subclass rather than on the base class).

Answer from Alex Martelli on Stack Overflow
🌐
Reddit
reddit.com › r/learnpython › creating instances in classes with __init__ method and without
r/learnpython on Reddit: Creating instances in classes with __init__ method and without
April 8, 2024 -

Hello everyone!

While learning about classes in Python, I encountered the following two questions. Consider the following two classes:

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

and

class Dog:
    def dog_constructor(self, name, age):
        self.name = name
        self.age = age

The main difference is that the first class contains an __init__ method, but the second one does not.

To create an instance in the first class, I used: my_dog = Dog('Willie', 5). However,

for the second one I tried: my_dog = Dog.dog_constructor('Willie', 10) which did not work. Then eventually

I was told that I should use

my_dog = Dog()
my_dog.dog_constructor('Willie', 5).

I am so confused about why we should use this approach.

Can anyone explain to me the importance of having an __init__ method in a class and why instances are created differently depending on whether we have __init__ or not?

I have been struggling with this for a while but still cannot grasp it.

I'd be very thankful for the explanation! Thank you!

Top answer
1 of 4
64

When feasible, letting __init__ get called (and make the call innocuous by suitable arguments) is preferable. However, should that require too much of a contortion, you do have an alternative, as long as you avoid the disastrous choice of using old-style classes (there is no good reason to use old-style classes in new code, and several good reasons not to)...:

   class String(object):
      ...

   bare_s = String.__new__(String)

This idiom is generally used in classmethods which are meant to work as "alternative constructors", so you'll usually see it used in ways such as...:

@classmethod 
def makeit(cls):
    self = cls.__new__(cls)
    # etc etc, then
    return self

(this way the classmethod will properly be inherited and generate subclass instances when called on a subclass rather than on the base class).

2 of 4
15

A trick the standard pickle and copy modules use is to create an empty class, instantiate the object using that, and then assign that instance's __class__ to the "real" class. e.g.

>>> class MyClass(object):
...     init = False
...     def __init__(self):
...         print 'init called!'
...         self.init = True
...     def hello(self):
...         print 'hello world!'
... 
>>> class Empty(object):
...     pass
... 
>>> a = MyClass()
init called!
>>> a.hello()
hello world!
>>> print a.init
True
>>> b = Empty()
>>> b.__class__ = MyClass
>>> b.hello()
hello world!
>>> print b.init
False

But note, this approach is very rarely necessary. Bypassing the __init__ can have some unexpected side effects, especially if you're not familiar with the original class, so make sure you know what you're doing.

🌐
Quora
quora.com › What-happens-if-you-define-a-python-class-without-an-__init__-function
What happens if you define a python class without an __init__ function? - Quora
You will have a place to put non-default initialization code when you need it. ... If a Python class has no __init__ method, then creating a new instance of the class will just create an empty instance of the class.
Top answer
1 of 6
86

You can circumvent __init__ by calling __new__ directly. Then you can create a object of the given type and call an alternative method for __init__. This is something that pickle would do.

However, first I'd like to stress very much that it is something that you shouldn't do and whatever you're trying to achieve, there are better ways to do it, some of which have been mentioned in the other answers. In particular, it's a bad idea to skip calling __init__.

When objects are created, more or less this happens:

a = A.__new__(A, *args, **kwargs)
a.__init__(*args, **kwargs)

You could skip the second step.

Here's why you shouldn't do this: The purpose of __init__ is to initialize the object, fill in all the fields and ensure that the __init__ methods of the parent classes are also called. With pickle it is an exception because it tries to store all the data associated with the object (including any fields/instance variables that are set for the object), and so anything that was set by __init__ the previous time would be restored by pickle, there's no need to call it again.

If you skip __init__ and use an alternative initializer, you'd have a sort of a code duplication - there would be two places where the instance variables are filled in, and it's easy to miss one of them in one of the initializers or accidentally make the two fill the fields act differently. This gives the possibility of subtle bugs that aren't that trivial to trace (you'd have to know which initializer was called), and the code will be more difficult to maintain. Not to mention that you'd be in an even bigger mess if you're using inheritance - the problems will go up the inheritance chain, because you'd have to use this alternative initializer everywhere up the chain.

Also by doing so you'd be more or less overriding Python's instance creation and making your own. Python already does that for you pretty well, no need to go reinventing it and it will confuse people using your code.

Here's what to best do instead: Use a single __init__ method that is to be called for all possible instantiations of the class that initializes all instance variables properly. For different modes of initialization use either of the two approaches:

  1. Support different signatures for __init__ that handle your cases by using optional arguments.
  2. Create several class methods that serve as alternative constructors. Make sure they all create instances of the class in the normal way (i.e. calling __init__), as shown by Roman Bodnarchuk, while performing additional work or whatever. It's best if they pass all the data to the class (and __init__ handles it), but if that's impossible or inconvenient, you can set some instance variables after the instance was created and __init__ is done initializing.

If __init__ has an optional step (e.g. like processing that data argument, although you'd have to be more specific), you can either make it an optional argument or make a normal method that does the processing... or both.

2 of 6
26

Use classmethod decorator for your Load method:

class B(object):    
    def __init__(self, name, data):
        self._Name = name
        #store data

    @classmethod
    def Load(cls, file, newName):
        f = open(file, "rb")
        s = pickle.load(f)
        f.close()

        return cls(newName, s)

So you can do:

loaded_obj = B.Load('filename.txt', 'foo')

Edit:

Anyway, if you still want to omit __init__ method, try __new__:

>>> class A(object):
...     def __init__(self):
...             print '__init__'
...
>>> A()
__init__
<__main__.A object at 0x800f1f710>
>>> a = A.__new__(A)
>>> a
<__main__.A object at 0x800f1fd50>
🌐
Sololearn
sololearn.com › en › Discuss › 2941542 › pythonclass-without-__init__-still-works
(python)class without __init__ still works? | Sololearn: Learn to code for FREE!
Explicitly writing __init__ makes it possible to set default parameters and object behavior, but even without explicit __init__ will be called when the object is created ... The reason is that in Python 3 all classes inherit from the object class.
🌐
CSDN
devpress.csdn.net › python › 63045285c67703293080b15f.html
How to create a class instance without calling initializer?_python_Mangs-Python
August 23, 2022 - With meta-classes still on the mind, the following answer shows how the problem can be solved both with and without them: #! /usr/bin/env python3 METHOD = 'metaclass' class NoInitMeta(type): def new(cls): return cls.__new__(cls) class String(metaclass=NoInitMeta if METHOD == 'metaclass' else type): def __init__(self, value): self.__value = tuple(value.split()) self.__alpha = tuple(filter(None, ( ''.join(c for c in word.casefold() if 'a' <= c <= 'z') for word in self.__value))) def __str__(self): return ' '.join(self.__value) def __eq__(self, other): if not isinstance(other, type(self)): return
🌐
Quora
quora.com › Is-it-possible-to-initialize-objects-without-explicitly-creating-them-using-classes-in-Python
Is it possible to initialize objects without explicitly creating them using classes in Python? - Quora
In Python every value is an object, even if you do not explicitly define it yourself (in which case you need to ‘call’ the class name to create an object of that class data type). So, whenever you use the (composite) value list, tuple, dictionary literals or (primitive) value literals int, float or str you are initializing an object of an internally defined class!
🌐
Python Forum
python-forum.io › thread-34797.html
Not including a constructor __init__ in the class definition...
September 1, 2021 - Hello Forum, We can create a class and include, at the very beginning, the __init__ special method called the constructor which can be parametrized or not. The __init__ method is called anytime an obj
Find elsewhere
Top answer
1 of 2
8

Every class has an __init__ method. If it doesn't explicitly define one, then it will inherit one from its parent class. In your 2nd example, the class inherits __init__ and a bunch of other methods (and other non-method attributes) from the base object class. We can see that via the dir function:

class Dog:
    def init_instance(self,name):
        self.name = name
        print('My name is',name)

print(dir(Dog))

output

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'init_instance']

__init__ gets called automatically after the instance is constructed (via the __new__ method), so we might as well use it if we need to initialize our instance. But we can call your init_instance explicitly:

bob = Dog()
bob.init_instance('Bob')
print(bob.name)    

output

My name is Bob
Bob

If you give you class an initializer that isn't named __init__ then it won't get called automatically. How should Python know that that method is an initializer? Although it's customary to make __init__ the first method in the class definition, that's by no means mandatory, and some people like to put __init__ last.

You said: "I have seen code where the init method has not been used, how come?" Well, some classes simply don't need their instances to be initialized: their instance attributes are set via various other methods, or by direct assignment in code outside the class definition, eg bob.color = 'brown'. Or they inherit a perfectly usable __init__ from a parent class.

2 of 2
1

init is nothing else then a method to initially prepare the state of your object. In other languages they have similar concepts as Constructors and it's not necessarily needed.

🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.4 documentation
Classes provide a means of bundling data and functionality together. Creating a new class creates a new type of object, allowing new instances of that type to be made. Each class instance can have ...
🌐
Real Python
realpython.com › python-class-constructor
Python Class Constructors: Control Your Object Instantiation – Real Python
January 19, 2025 - Python handles instantiation internally with .__new__() for creation and .__init__() for initialization. You can customize object initialization by overriding the .__init__() method in your class.
🌐
JMFT
jmft.dev › static-factory-methods-in-python.html
JMFT – Object creation patterns in Python: Static factory methods
May 20, 2024 - The rest of this post will discuss the static factory methods pattern, which allows you to provide multiple, distinct ways to instantiate a class without having a complicated __init__() method. In a future post I shall discuss the builder pattern, which lets you gradually build up a complex object by passing around the information needed to create it rather than requiring all the information in one go. Goal: Provide multiple, distinct ways of instantiating a class. Explicit is better than implicit. The Zen of Python
🌐
DEV Community
dev.to › delta456 › python-init-is-not-a-constructor-12on
Python: __init__() is not the only constructor - DEV Community
February 8, 2020 - Instead, it's an initializer - it initializes an instance object. As an example, and there are probably more ways to do this, you could override __new__ to limit the number of instances of an object that can be created, or to obtain them from a pool, that sort of idea. So there are probably use-cases for overriding __new__ but I doubt that you'd need to worry about it for everyday usage. Update: I looked into the nomenclature, and it does not seem to me that Python has the concept of "constructor" used in the documentation in the same way that it's used for languages like Java or C++. Instead the docs mention that the call used to create an object, like say Foo(), is a constructor expression:
Top answer
1 of 6
33

In Python you can add members dynamically to an object, but (1) the name must already exist (it must have been assigned) and (2) it must be bound to an instance of some class. To do so you may create an empty class:

class Empty:
    pass        # empty statement otherwise the class declaration cannot succeed

construct an instance of it and assign it to your variable

person = Empty()

and then add whatever data you want

person.name = 'Mike'
person.age = 25
person.gender = 'male'

On the other hand, if you don't need the additional features a "normal" class provides and you just want to store some data in a key=>value fashion you should probably just use a dictionary.

person={}
person['name']='Mike'
person['age']=25
person['gender']='male'

(notice that, at least up to Python 2.7, this is mostly just a stylistic/syntactic difference, since instance members are implemented underneath in terms of dictionaries)

As a general guideline, you want classes when you are instantiating multiple objects made in the same way (and where typically the assignment to the members is done in the class constructor; adding members later generally makes for difficult to follow code), dictionaries otherwise.

2 of 6
19

Python won't magically create a container object when you start assigning attributes to it, and if matlab allows this, I'd consider matlab badly broken. Consider this:

person.name = "Mike"
persom.age  = 25
person.sex  = "Male"

Now we have two objects, person and persom, and person doesn't have age, and there was no hint that this happened. Later you try to print person.age and, one would hope, matlab then complains... two pages after the actual mistake.

A class can itself be used as a container or namespace. There's no need to instantiate it, and it'll save you a bit of typing if you just want a bundle of attributes.

class sex:
    male   = "M"
    female = "F"

class person:
    name = "Mike"
    age  = 25
    sex  = sex.male

To access or modify any of these, you can use person.name, etc.

N.B. I used a class for sex as well to illustrate one of the benefits of doing so: it provides consistency in data values (no remembering whether you used "M" or "Male" or "male") and catches typos (i.e. Python will complain about sex.mlae but not about the string "mlae" and if you were later checking it against "male" the latter would fail).

Of course, you still run the risk of misspelling name, age, or sex in this type of class definition. So what you can do is use the class as a template and instantiate it.

class Person:
    def __init__(self, name, age=None, sex=None):
        self.name, self.age, self.sex = name, age, sex

Now when you do:

person = Person("Mike", 25, sex.male)

or if you want to document what all those parameters are:

person = Person("Mike", age=25, sex=sex.male)

it is pretty much impossible to end up with an object that has a misspelled attribute name. If you mess it up, Python will give you an error message at the point you made the mistake. That's just one reason to do it this way.

🌐
Reddit
reddit.com › r/learnpython › how is this code creating objects without constructors or instance attributes? please see the description
r/learnpython on Reddit: How is this code creating objects without constructors or instance attributes? Please see the description
June 28, 2023 -

I'm working with Flask and using SQL Alchemy ORM and there is something I would like to understand in the code. SQLAlchemy allows the creation of model class by extending the db.Model And in the model class we declare class attributes instead of instance attributes. Why is that ?

We don't even have a constructor or __init__ method and yet we are able to create objects by passing arguments (and that too on the freaking class attributes). How is this working ?

from flask_sqlalchemy import SQLAlchemy

from flask import Flask

app = Flask(name) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' db = SQLAlchemy(app)

class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) password = db.Column(db.String(60), nullable=False)

def __repr__(self):
    return f"User('{self.username}', '{self.email}')"

with app.app_context(): db.create_all()

# how is the user getting created here with any init method in the User class
user1 = User(username="foo", email="foo@demo.com", password="foobar")
print(user1)
db.session.add(user1)
db.session.commit()
print(User.query.all())

🌐
CodeQL
codeql.github.com › codeql-query-help › python › py-missing-call-to-init
Missing call to superclass __init__ during object initialization — CodeQL query help documentation
If the __init__ method of a superclass is not called during object initialization, this can lead to errors due to the object not being fully initialized, such as having missing attributes.