'How can I call a function from another file which contains an object defined in the main_file?

I have these two files:
main.py

def func_a():
    return object_a.method()


class ClassA:
    def __init__(self):
        pass

    def method(self):
        return "k"


if __name__ == '__main__':
    object_a = ClassA()
    print(func_a())
    import file_1

and file_1.py

import main


print(main.func_a())

I get these errors:

Traceback (most recent call last):
  File "C:\Users\Utente\PycharmProjects\pythonProject\main.py", line 16, in <module>
    import file_1
  File "C:\Users\Utente\PycharmProjects\pythonProject\file_1.py", line 4, in <module>
    print(main.func_a())
  File "C:\Users\Utente\PycharmProjects\pythonProject\main.py", line 2, in func_a
    return object_a.method()
NameError: name 'object_a' is not defined. 

I would like to create object_a once by starting main.py, and have the object_a methods used by calling func_a from other files (which will be executed by main.py)



Solution 1:[1]

since __name__ != "__main__", object_a is never created in main.py. If you remove object_a = ClassA() from the if then it will run fine.

Solution 2:[2]

It is confusing, because you are expecting that having run the line: object_a = ClassA() that object_a will be attached to the main module.

You could try adding this as your first line of main.py:

print('top of main', __name__)

You will see this line execute twice as you are expecting, but with different outcomes.

Solution 3:[3]

What you should actually do to get what you want is to strip almost everything out of main.py except this:

if __name__ == '__main__':
    object_a = ClassA()
    print(func_a())
    import file_1

plus enough imports to make this bit work, plus this: set_object_a(object_a)

Thus main.py can become:

if __name__ == '__main__':
    set_object_a(ClassA())
    print(func_a())
    import file_1

Now everything else you had needs to go in another module all by itself like this:

# notmain.py
object_a = None

def set_object_a(a):
    global object_a
    object_a = a

def func_a():
    return object_a.method()

class ClassA:
    def __init__(self):
        pass

    def method(self):
        return "k"

Now you can have any other modules do this and similar:

import notmain

print(notmain.func_a())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 CasualScience
Solution 2 quamrana
Solution 3 quamrana