pythonoopmodular-design

Wrong output when dealing with multiple python files for one project


Sorry if I asked a silly question or made an obvious mistake as OOPS is not my strong point!

I have a project for which I am using Python. I have written all the code in a single function and it works as expected, giving proper output dataframe.

But when I try to break that one function into multiple functions all present in different .py files, all the files present in one local directory, the output then gets changed. The output dataframe then contains all nan values.

main.py (only one file which contains all the code)

    def fn():
        .
        .
        .
        return x

Here x is the expected result and it works. But if I do this:

sub_module1.py (file #1)

class a:
    def __init__(self):
        pass:
    
    def fn1(self, para1):
        .
        .
        return x


sub_module2.py (file #2)

class b:
    def__init__(self):
        pass:

    def fn2(self, para2):
        .
        .
        return y


main.py (file #3)

from sub_module1 import a
from sub_module2 import b

x1 = a().fn1(para1)
x2 = b().fn2(para2)

def fn3(some parameters):
    # some logic which makes use of x1 and x2
    return new_x

new_x has nan values which don't make sense to me as the code is the same as used in main.py. The only difference is that instead of using one single function for the whole code, I have broken down the code into multiple functions which are stored in different python files but in the same directory and then I am calling those functions into one single python file(main.py) to get the output.

Any help is appreciated!


Solution

  • From what I can gather, there is an issue with the logic inside fn3() or the way you are calling fn3().

    If you are calling fn3() as shown below -

    # main.py (file #3)
    
    from sub_module1 import a
    from sub_module2 import b
    
    x1 = a().fn1(para1)
    x2 = b().fn2(para2)
    
    def fn3(some parameters):
        # some logic which makes use of x1 and x2
        return new_x
    
    if __name__ == '__main__':
        new_x = fn3(some parameters)
    

    Then what will happen is that x1 and x2 values will not have the values returned by your methods as their initialization is done outside the scope of f3(). Also, I hope some parameters include x1 and x2. If it doesn't, it's better to make sure that you are doing that explicitly. I would rewrite your code to do the following -

    # main.py (file #3)
    
    from sub_module1 import a
    from sub_module2 import b
    
    def fn3(some parameters, x1, x2):
        # some logic which makes use of x1 and x2
        return new_x
    
    if __name__ == '__main__':
        x1 = a().fn1(para1)
        # print(x1) for sanity checking.
        x2 = b().fn2(para2)
        # print(x2) for sanity checking.
        new_x = fn3(some parameters, x1, x2)
    

    The alternate approach is to get the values of x1 and x2 inside fn3(). Then your code would look as follows -

    # main.py (file #3)
    
    from sub_module1 import a
    from sub_module2 import b
    
    def fn3(some parameters):
        x1 = a().fn1(para1)
        # print(x1) for sanity checking.
        x2 = b().fn2(para2)
        # print(x2) for sanity checking.
        # some logic which makes use of x1 and x2
        return new_x
    
    if __name__ == '__main__':
        new_x = fn3(some parameters)
    

    If this still returns new_x as a NAN value, I would debug line by line what's happening inside fn3() as the issue surely lies over there.