Menu

Python Module – What are modules and packages in python?

Any Python file with a .py extension is a Module in Python. A python package is a collection of such modules along with a __init__.py file. Let’s understand how to work with modules and packages with clear examples.

Introduction

When you work on python projects, it’s not a good practice to have all you python code in one single python file (.py).
You are better off splitting your code, classes, functions and variables thoughtfully in separate python files (.py files), aka modules. Python allows you to import code in one module for use in other modules.

This will:
1. Make your code modular, there by make the python objects reusable across modules.
2. Allows you to focus on a small part of problem at a time without disturbing the whole.
3. Makes bug fixing easier.
4. Allow multiple developers to contribute to your project effectively
5. Organize the code and maintain the project a lot more easier.

So what is a Package? and how is it different from a module?

What is a Module and Package?

A Python module is any Python files with a .py extension. It can be imported into python without the .py part.

A Python package is nothing but a collection of modules along with a __init__.py file. The modules can also be arranged in hierarchy of folders inside a package.

Just by adding an empty __init__.py file to the in the folder, Python knows it is a Package.

In fact, a package is also really a module that contains other modules.

Python provides a wide variety of modules as standard modules. You can find the full list here.

Pre-requisite to follow along the code below

To follow along the code, download this file and extract it. Then, open your project from it. That is in your terminal or command prompt, do cd folder_name and type jupyter notebook if you have anaconda installed. Or if you are using VSCode, Pycharm etc, open your project from this folder.

Once inside you can see python files and folders.

The python file cars.py can be imported in python as a module. In fact, the type such an imported object is module.

# Import the cars.py file as a `cars` module
import cars
type(cars)

#> module

Inside the python module (the .py file) you can define one or more class and import them.

# Import a class from the file
from cars import Car

Initialize and start using.

# Start the car
car1 = Car(make="Toyota", model="Camry")

# Start driving
car1.start()

#> …VROOOOM….Started!

Stop.

car1.stop()
car1.check_speed_and_gear()

I’m driving at: 0 in gear: 0

Package Example

You can also import from the cars package. You will see the carspackage folder inside. Since this contains a __init__.py, this is a python package.

Inside it also contains cars.py and suv.py.

from carspackage import cars as carsp
from carspackage import suv as suvp

#> name: carspackage.cars
#> I am outside the guard!

Instantiate

car2 = carsp.Car(make="Toyota", model="Camry")
car2

#> Make Toyota, model: Camry

Start using..

# Start driving
car2.start()

#> …VROOOOM….Started!

Accelerate..

car1.accelerate()
car1.check_speed_and_gear()
car1.stop()

#> I’m driving at: 5 in gear: 0

Now, let’s try running the SUV

suv1 = suvp.SUV(make="Honda", model="CRV")
suv1.start_drive()
suv1.check_speed_and_gear()

#> Init success!!
#> Shift Up and Drive.
#> I am driving at 5 mph
#> I’m driving at: 5 in gear: 1

suv1.stop()

Purpose of __main__.py

Just like how you call a python script in terminal python my_code.py, you can call your package from command prompt / terminal as well via python {pacakge_name}.

But when called so, which module / code will be run?

That is the purpose of __main__.py

When a package is called from terminal, the Python will look for executing the contents of __main__.py file inside the package.

In practical uses, have a python package designed to do a spacific task, say convert a color image to b/w, you can build your scripts as a package and pass the path to image you to convert as an argument to python pkgname --image.png.

Let’s call carspackage from terminal / command prompt.

!python carspackage

#> name: cars
#> Let’s create a Toyota RAV4!
#> Make is Toyota, Model is RAV4

#> —————————

That simply executed the __main__.py.

You can make it receive arguments from the user as well.

Receiving command line arguments

What are command line arguments?

When you call a python program or a pacakge, you can pass additional input values based on which the output of your python program can change.

For example:

a. An email sending program may receive the ‘To address’ as an input
b. A program to process data can take the number of lines of data as input.

The simplest way to pass argument to your python script from command is using sys.argv()

Now, uncomment the sys.argv part inside __main.py__ and run the below code.

!python carspackage make="Toyota" model="RAV4

#> name: cars
#> Let’s create a Toyota RAV4!
#> Make is Toyota, Model is RAV4

#> —————————

A more sophisticated and convenient way of receiving and processing arguments is provided by the argparse package. This is part of python standard library and has been adopted by developers.

Packages with hierarchy

The carspackagedeep folder contains contains folders that contain the python files. So, it’s 1 additional level deep.

So, you need to point to that folder and then import the module.

from carspackagedeep.Car import cars

#> name: carspackagedeep.Car.cars

Now, import suv as well.

from carspackagedeep.Suv import suv

#> I am outside the guard!

If you notice the contents of suv.py, it contains a __name__ == "__main__" statement. why?

What does __name__ == “__main__” do?

Whenever the Python interpreter reads a source file, it does two things:

  1. It sets a few special variables like __name__
  2. It executes all of the code found in the file.

When you import a python package or module, all the code present in the module is run.

So, when you run import mypackage, there is every chance that certain code present in mypackage you didn’t want to execute may get executed on import.

You can prevent this by checking the condition: __name__ == "__main__". It acts as a guard. The parts of your code that you don’t want to be run can be placed inside the __name__ == "__main__" condition block.

If the code is run when getting imported from another package, the value of __name__ will bear the path/name of the module. For example: the value of __name__ for ‘carspackage/cars.py’ when called from other places will be carspackage.cars.

Only when you are directly running python carspackage/cars.py, that is, only when you run the module as the main program, the value of __name__ will be __main__.

!python carspackage/cars.py

When run this way, all the code inside the guard will get executed.

Course Preview

Machine Learning A-Z™: Hands-On Python & R In Data Science

Free Sample Videos:

Machine Learning A-Z™: Hands-On Python & R In Data Science

Machine Learning A-Z™: Hands-On Python & R In Data Science

Machine Learning A-Z™: Hands-On Python & R In Data Science

Machine Learning A-Z™: Hands-On Python & R In Data Science

Machine Learning A-Z™: Hands-On Python & R In Data Science