Difference between Module and Class in Python

Each Answer to this Q is separated by one/two green lines.

Can I assign value to a variable in the module? If yes, what is the difference between a class and module?

PS: I’m a Java guy (in case it helps in the way of explaining). Thanks.

There are huge differences between classes and modules in Python.

Classes are blueprints that allow you to create instances with attributes and bound functionality. Classes support inheritance, metaclasses, and descriptors.

Modules can’t do any of this, modules are essentially singleton instances of an internal module class, and all their globals are attributes on the module instance. You can manipulate those attributes as needed (add, remove and update), but take into account that these still form the global namespace for all code defined in that module.

From a Java perspective, classes are not all that different here. Modules can contain more than just one class however; functions and any the result of any other Python expression can be globals in a module too.

So as a general ballpark guideline:

  • Use classes as blueprints for objects that model your problem domain.
  • Use modules to collect functionality into logical units.

Then store data where it makes sense to your application. Global state goes in modules (and functions and classes are just as much global state, loaded at the start). Everything else goes into other data structures, including instances of classes.

  • Module:

    A module is a file containing Python definitions and statements.

As the doc say.

So a module in python is simply a way to organize the code, and it contains either python classes or just functions.
If you need those classes or functions in your project, you just import them.
For instance, the math module in python contains just a bunch of functions, and you just call those needed (math.sin).
Just have a look at this question.

On the other hand a python class is something similar to a java class, it’s only structured in a slightly different way.

Can I assign value to a variable in the module?
In short yes.


The concept of module refers to a single Python file which can be imported (by importing, you have the access to the variables/methods/classes defined in that module).

It is commonly discussed together with the concept package, which is a folder with __init__.py. A package can contain sub-packages or modules, and at the same time, similar to modules, can define variables/methods/classes to be imported inside its __init__.py.

The purpose of having modules/packages in Python is kind of similar to having packages in Java: to contain and categorize reusable codes, to resolve naming confliction and so on.


Besides, Python also has a builtin class named module, just like list, tuple, dict (note that Python builtin classes do not follow the CapWords naming convention due to legacy reasons). A module instance represents the module/package imported.

When you use the import statement to import a module (single Python file) or a package (folder with __init__.py), typically
1. a new instance of module class will be created
2. the classes/methods/variables you defined in that imported Python file will be added as the attributes of this module instance (if it is a package, it will be the classes/methods/variables defined in __init__.py that are added).

Therefore, since it is just an instance of module class, you can assign a value to the attribute of that instance and other class instance operations.

import math

print(type([1,2,3]))
print(type(math))
print(dir([1,2,3]))
print(dir(math))

console:

<class 'list'>
<class 'module'>
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']

In python world, module is a python file (.py) inside a package. Package is a folder that has __init__.py in its root. It is a way to organize your codes physically (in files and folders).

On the other hand, class is an abstraction that gathers data (characteristics) and method (behavior) definitions to represent a specific type of objects. It is a way to organize your codes logically.

A module can have zero or one or multiple classes. A class can be implemented in one or more .py files (modules).

But often, we can organize a set of variables and functions into a class definition or just simply put them in a .py file and call it a module.

Likewise in system design, you can have elaborate logical modeling or just skip it and jump into physical modeling. But for very complex systems, it is better not to skip the logical modeling. For simpler systems, go KISS.

How to organize your code

This is how I decide to organize my code in classes or modules:

Class is supposed to be a blueprint to create (many) instances of objects based on that blueprint. Moreover, classes can have sub-classes (inheritance).

Therefore, if I need inheritance or (many) instantiations, I gather functions and variables under a class definition (methods and properties).

Otherwise, I Keep It Simple and Stupid (KISS) and use modules.

A good indication of a bad class (that should have been a module): you can rewrite all your object methods and properties with static methods and properties.

It is like a concept: Module > Class > Function in Python. Here is an example of the usage of this idea in unit test tool, Pytest about Fixture Scope across Classes, Modules.


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .