Run threads simultaneously in python

Question:

So, I’m trying to run 2 threads simultaneously.
My code looks like this:

from threading import Thread
def Main():
    n = 10
    k = 2
    max = n//k
    def firstfunc():
        for i in range(0, max):
            print(i)
    def secondfunc():
        for i in range(0, max):
            print(i+10)

if __name__ == '__main__':
    T1 = Thread(target=Main().firstfunc, args=()).start
    T2 = Thread(target=Main().secondfunc, args=()).start
    for thread in [T1, T2]:
        thread.join()

The error that throws:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In [2], line 14
     11             print(i+10)
     13 if __name__ == '__main__':
---> 14     T1 = Thread(target=Main().firstfunc, args=()).start
     15     T2 = Thread(target=Main().secondfunc, args=()).start
     16     for thread in [T1, T2]:

AttributeError: 'NoneType' object has no attribute 'firstfunc'

I searched online and I consulted also stackoverflow’s answers to similar questions, but nothing worked for me. Does anyone know what I’m doing wrong?

Asked By: Edoardo Balducci

||

Answers:

Main() returns None because you don’t return anything from it in your code. Thus Main().firstfunc is an error just like None.firstfunc, because 'NoneType' object has no attribute 'firstfunc'.

In general, it’s not possible to access local variables of functions (n, k, max, firstfunc, secondfunc are Main‘s local variables), and they don’t automatically become attributes of the function or its return value.

You can return the functions themselves:

def Main():
    n = 10
    k = 2
    max = n//k
    def firstfunc():
        for i in range(0, max):
            print(i)
    def secondfunc():
        for i in range(0, max):
            print(i+10)

    return firstfunc, secondfunc

if __name__ == '__main__':
    first, second = Main()
    T1 = Thread(target=first, args=())
    T2 = Thread(target=second, args=())
    for thread in (T1, T2):
        thread.start() # CALL the `start` method!
    for thread in [T1, T2]:
        thread.join()

Example output:

0
1
10
2
3
4
11
12
13
14
Answered By: ForceBru

The error says that there is because Main function return None and None dont have attirbute firstfunc and so on.

my suggestion just change to class like this:

from threading import Thread
class MyClass:
    n = 10
    k = 2
    border = n//k
    def firstfunc(a):
        global border
        for i in range(MyClass.border):
            print(i)
    def secondfunc(b):
        for i in range(MyClass.border):
            print(i+10)

if __name__ == '__main__':
    T1 = Thread(target=MyClass().firstfunc, args=())
    T1.start()
    T2 = Thread(target=MyClass().secondfunc, args=())
    T2.start()

    for thread in [T1, T2]:
        thread.join()
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.