Javascript required
Skip to content Skip to sidebar Skip to footer

Python How to Separate Code Into Separate Files

Each Module/file has its own global variable

When you create a variable (not within a function) in a Python file, you mount this variable to the namespace of the current module. Every command in this Python file can access, read, and modify the value of the variable, that is, it becomes a global variable. You can also explicitly make a variable defined within the functions globally by declaring itglobal.

make a local variable global (image by author)

However, global variables are not shared across different Python files. To illustrate that, let us look at the following example:

Global variables are unique to each module (image by author)

The logic is very clear, I defined a function in sub_module.py and try to invoke it in main.py file. It seems like I defined variable num=5 in the main.py file but it turns out the function can not access it, the reason is sub_module.py can not access the global variable in other Python modules, so the num=5 is invisible to the program. How to fix it? Just define num in the right file.

Define a variable in the sub_module.py (image by author)

Python function always remembers the place it gets created

I am not sure if you ever experience any confusion about the above example? I did when I first looked at this example because I explicitly imported test_func1 from sub_module.py to the main.py, it is natural to think that the function has already been in the current scope, isn't it?

But the Python function always knows where it was created. Even though it seems like test_func1 is in main.py, it still belongs to the sub_module.py when gets executed because this is where it was created. Now here comes to another useful practical tips:

Remember to import necessary packages in the sub module as well!

Forget to import NumPy in sub module (image by author)

In the above example, since we forgot to import the NumPy package in the sub_module.py , even though we have it imported in main.py it is still not accessible to test_func1 . Now let's fix it:

import Numpy package in sub module as well (image by author)

Passing by reference versus Passing by value

The first example works, but looks weird, isn't it? Usually, we will just define function and class in the submodule instead of putting a single variable num=5 . The common way to solve this problem is actually to add num as an argument in the test_func1 and also pass the num=5 to the function when invoking it in main.py file.

Pass variable as an argument (image by author)

Now the question is, how could doing so make the sub_module.py recognize where the num is? It is because Python always passes by reference instead of passing by value. To illustrate it, let's look at what's actually going on when you invoke the function:

Pass by reference versus pass by value (image by author)

When you type num=5 in the main.py , you basically create a PyObject with integer type which lives in a piece of physical memory, and you use the name num to point to this piece of physical memory. Now since Python always pass by reference, so you can think of the test_func1 will know where the name num points to. As a result, it will have the access to the value 5 since it literally knows where this value lies.

Can I have a shared global variable across different files?

As we discussed, the global variable is unique to its own module. But sometimes we really want to have a GLOBAL variable that can be accessed, modified by every Python file in the directory. The canonical way to achieve this is to create another file with your GLOBAL variables.

A separate file to hold the GLOBAL variable (image by author)

I purposely made this example a bit complicated; here we have a gloabl_.py python file that contains num=10 . But in the main.py file, I created an num=5 as well. It can tell you the differences even though they were both named as num , but they are in a different scope. In the main.py , we modify this GLOBAL variable by adding 1, and the change will be reflected in sub_module.py as well. Noting here I have to import global_ within the test_func2 function because if I put the import syntax in the beginning, num it imported will be the one prior to the execution of lineglobal_.num += 1 . Remember, the sub_module.py got executed in the line from sub_module import * , we can test it in the following example:

Order of import syntax matters a lot (image by author)

As you saw, now even though the global variable num has incremented by 1, it wasn't reflected in sub_module.py since the variable they imported came from before the operation. When importing, Python will automatically make a copy for you so the old global_.numand new global_.num live in totally different physical memory.

Conclusion

Here comes some best practices when dealing with multiple Python files:

  1. Pass the variable as the argument, since Python "pass by reference", which guarantees that your sub module can access the variable you passed.
  2. Don't forget to import the necessary package in the sub module as well, since the function always remembers where it got created.
  3. Using a separate file to hold the GLOBAL variable across Python modules but keep in mind that importing the GLOBAL variable will make a copy of the original one so always check if you are referring to the right variable in your program.

That's about it! I hope you find this article interesting and useful, thanks for reading! If you like this article, follow me on medium, thank you so much for your support. Connect me on my Twitter or LinkedIn, also please let me know if you have any questions or what kind of tutorials you would like to see In the future!

Python How to Separate Code Into Separate Files

Source: https://towardsdatascience.com/common-mistakes-when-dealing-with-multiple-python-files-b4f4dc4d5643