Home > Enterprise >  How to call a function inside main function from library in Python
How to call a function inside main function from library in Python

Time:03-28

I've a second.py as library which is called by main.py. I want to call a function inside main.py when a loop in second.py trigger. Here is the basic structure of my code. (The whole code is much bigger, I just simplified it, so structure should not be changed)

# main.py
import second


class Main:
    def __init__(self):
        self.second_functions = second
        self.data_from_second = None

    def func1(self):
        # Initiate something in second
        print(self.second_functions.SecondClass.test1(self))

    def func2(self, data):
        # Do something with data
        self.data_from_second = data
        print(f"{data}")


Main().func1()
# second.py
import time


class SomeHandler:
    pass


class SecondClass(SomeHandler):
    def __init__(self):
        self.something = "Something"

    def test1(self):
        # do some stuff
        self.something = "Initiated"
        print("Second Class Initiated")

        while 1:
            # !!! from this point I want to trigger func2() in running main.py
            print("Trigger func2('some data')")
            # Main.func2("DATA") #When I try someting like this, it returns "NameError: name 'Main' is not defined" which is normal.
            time.sleep(3)

second.py is actualy a socket server. When client sends something, I need to pass that info to main.py. Currently main.py call a function inside second.py in interval to get datas which is not right way I believe.

CodePudding user response:

You need to import main (or rather from main import Main) in second.py, because currently second.py doesn't know what is 'Main'.

However it is not possible to import main in this case, due to a circular dependency issue, for which there are answers here: Circular import dependency in Python

Also be aware that you can't call Main.func2("data"), because func2 is not a @classmethod, main needs to be instantiated first with brackets Main() or use the @classmethod decorator in Main.func2().

CodePudding user response:

Just provide the reference to func2 to the SecondClass.test1() call:

# main.py
import second


class Main:    
    def __init__(self):
        self.second_functions = second
        self.data_from_second = None
enter code here
    def func1(self):
        # Initiate something in second
        inst = second_functions.SecondClass()
        print(inst.test1(callback=self.func2))

    def func2(self, data):
        # Do something with data
        self.data_from_second = data
        print(f"{data}")


Main().func1()

Notice how we can now call the fn and pass it data. This is a callback pattern.

# second.py
import time


class SomeHandler:
    pass


class SecondClass(SomeHandler):
    def __init__(self):
        self.something = "Something"

    def test1(self, callback):
        # do some stuff
        self.something = "Initiated"
        print("Second Class Initiated")

        while 1:
            data = 123
            callback(data)
            time.sleep(3)
  • Related