Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Thread.__init__(self) in a class work?

So I found this code:

from threading import Thread
class Example(Thread):
    def __init__(self):
        Thread.__init__(self)

    def run (self):
        print("It's working!")
Example().start()

And it prints "It's working!" using another thread, but how does this work? I can't find anything about Thread.__init__(self) in a class. Does it have something to do with superclasses?

like image 374
Maurits van Altvorst Avatar asked Dec 24 '22 16:12

Maurits van Altvorst


2 Answers

Your __init__ method is entirely redundant. You are in effect replacing Thread.__init__() with your own implementation, where your own implementation simply calls Thread.__init__(). If you removed it, nothing would change:

class Example(Thread):
    def run (self):
        print("It works!")

Your Example.run() method is simply called because you started the thread using the Thread.start() method:

start()
Start the thread’s activity.

It must be called at most once per thread object. It arranges for the object’s run() method to be invoked in a separate thread of control.

Also see the Thread.run() documentation:

run()
Method representing the thread’s activity.

You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.

Your __init__ method had nothing to do with that.

Now, if you created a __init__ method in a Thread subclass and then did not make sure Thread.__init__ was called, then you prevented the class from setting important instance information, breaking instances:

>>> from threading import Thread
>>> class Example(Thread):
...     def run (self):
...         print("It works!")
... 
>>> Example().start()
It works!

>>> class BrokenExample(Thread):
...     def __init__(self):
...         # not doing anything
...         pass
...     def run (self):
...         print("It works!")
... 
>>> BrokenExample().start()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../lib/python2.7/threading.py", line 737, in start
    raise RuntimeError("thread.__init__() not called")
RuntimeError: thread.__init__() not called

Because this is a common error to make, the Thread.start method throws a custom exception to tell you explicitly that Thread.__init__ was not executed.

like image 95
Martijn Pieters Avatar answered Jan 07 '23 17:01

Martijn Pieters


__init__() method is called when an object is initialized. And when you do - Thread.__init__(self) , it just just calling the parent class' __init__() method .

Like said in comment you can remove it and the functionality should remain same. In your class the __init__() is completely redundant.

This method is called when you do -

Example()

When you create the new object for Example() .

The run() method is called, when you do - .start() on the Example() object. This is done by the Thread.start() method, from documentation -

start()

Start the thread’s activity.

It must be called at most once per thread object. It arranges for the object’s run() method to be invoked in a separate thread of control.


Adding one more print statement and dividing Example().start() into two lines so you can understand this clearly -

>>> from threading import Thread
>>> class Example(Thread):
...     def __init__(self):
...         Thread.__init__(self)
...         print("In __init__")
...     def run (self):
...         print("It's working!")
...
>>> e = Example()
In __init__
>>> e.start()
It's working!
like image 39
Anand S Kumar Avatar answered Jan 07 '23 17:01

Anand S Kumar