Three tips for easily importing and executing Python modules

introduction

As a programmer, you certainly want to share the useful modules you create with other users on your team. Although your module may be useful, if others need to spend a lot of energy accessing useful functions in the module, others will not use it.

Therefore, if you want to make your module easy for users to use, the code to import and run the module should be short. This article will show you three ways to simplify importing and executing Python modules.

Import

scene

Suppose we have one called utils Py file, which contains all important functions and classes

def add_two(num: int):
    return num + 2   

def multiply_by_two(num: int):
    return num * 2 

a = 5 

In another script, we use from utils import * to import from utils Py, except for variable a. What should we do?

Solution

It's easy to do this by adding all = ["add_two", "multiply_by_two"]. When using import *, the functions, classes, and packages specified in all * will be imported.

__all__ = ["add_two", "multiply_by_two"]

def add_two(num: int):
    return num + 2   

def multiply_by_two(num: int):
    return num * 2 

a = 5 

Now try using import in another script*

from utils import *

num = 3 
print(add_two(num))
print(multiply_by_two(num))
print(a)
5
6
Traceback (most recent call last):
  File "main.py", line 6, in <module>
    print(a)
NameError: name 'a' is not defined

Cool! This error tells us that only from utils Add has been imported into py_ Two and multiply_by_two instead of importing variable a.

Merge multiple files

scene

Imagine the structure of the files in our directory as follows:

.
├── data_modules
│   ├── load_data.py
│   └── process_data.py
└── main.py

load_data.py is as follows:

class DataLoader:
    def __init__(self, data_dir: str):
        self.data_dir = data_dir

    def load_data(self):
        print(f"Loading data from {self.data_dir}")

process _ data.py is as follows:

class DataProcessor: 
    def __init__(self, data_name: str):
        self.data_name = data_name
    
    def process_data(self):
        print(f"Processing {self.data_name}")

To use classes from two different files, we need to import each class from each file.

from data_modules.load_data import DataLoader
from data_modules.process_data import DataProcessor

data_loader = DataLoader('data/')
data_loader.load_data()

data_processor = DataProcessor('data1')
data_processor.process_data()

This method is very good, but using two import statements is very cumbersome. Is there a way that we can turn two import statements into one import statement, as shown below.

from data_modules import DataLoader, DataProcessor

Solution

In data_ Insert in modules directory_ init _. py file can easily solve this problem:

touch data_modules/__init__.py

Then insert the previously mentioned import statement into the_ init _. py file:

from .load_data import DataLoader
from .process_data import DataProcessor

We use a "." here, Because load_data.py and_ init _. py is in the same directory.

Now, let's try from data_modules import DataLoader and DataProcessor.

from data_modules import DataLoader, DataProcessor

data_loader = DataLoader('data/')
data_loader.load_data()

data_processor = DataProcessor('data1')
data_processor.process_data()
Loading data from data/
Processing data1

fantastic! succeed!

Run the directory like a script

scene

Our catalogue is as follows:

.
└── data_modules
    ├── __init__.py
    ├── load_data.py
    ├── main.py
    └── process_data.py

When we run main Py is like this:

$ python data_modules/main.py

We may want to simplify the way users or teammates run main Py code, just run the parent directory:

$ python data_modules

This is better than running data_modules/main.py is better because it is shorter and users do not need to know data_ Which files are in modules.

How can we do that?

Solution

At this time__ Main__ Py comes in handy. Just change the script to run when you run the top-level directory to__ main__.py. In our example, we need to put main Py becomes__ Main__ py.

# Rename main.py to __main__.py
$ mv data_modules/main.py data_modules/__main__.py

Our new catalog will look like this

.
└── data_modules
    ├── __init__.py
    ├── load_data.py
    ├── __main__.py
    └── process_data.py

Now let's test it

$ python data_modules
Loading data from data/
Processing data1

The effect is very good!

summary

In this article, we learned how to make it easier for you and those who use your package. I hope I can help you~

Tags: Python

Posted by bloodl on Thu, 14 Apr 2022 15:03:40 +0930