Python Private Functions

Summary: in this tutorial, you’ll learn how to define Python private functions in a module using the __all__ variable.

Suppose you have a module called mail.py with two functions send() and attach_file().

def send(email, message):
    print(f'Sending "{message}" to {email}')

def attach_file(filename):
    print(f'Attach {filename} to the message')
   Code language: Python (python)

And you want to expose only the send() function to other modules, not the attach_file() function. In other words, you want the attach_file() function to be private and cannot be accessible from the outside of the mail module.

Note that for simplicity, we only print out some texts in the functions.

If other modules use the import * statement like this:

from mail import *Code language: Python (python)

you can prefix a function name with an underscore (_) to make it private. For example:

def send(email, message):
    print(f'Sending "{message}" to {email}')

def _attach_file(filename):
    print(f'Attach {filename} to the message')
   Code language: Python (python)

From the mail.py file, you can use the import * from mail module and can see only the send() function:

from mail import *


send('[email protected]','Hello')Code language: Python (python)

In other words, you won’t be able to access the _attach_file() function from the main module. If you attempt to call the _attach_file() function, you’ll get an error.

Another way to make the attach_file() function private is to use the __all__ variable. In this way, you don’t need to prefix the function name with an underscore (_) to make it private.

The __all__ specifies a list of functions (also variables, and other objects) that are available to the other modules. In other words, you can make a function private by not listing it in the __all__ variable.

The following uses the __all__ variable in the mail module to make the send() function public and attach_file() function private:

# mail.py

__all__ = ['send']

def send(email, message):
    print(f'Sending "{message}" to {email}')

def attach_file(filename):
    print(f'Attach {filename} to the message')
   Code language: Python (python)

From the main.py module, you also cannot access the attach_file() function like before:

# main.py

from mail import *


send('[email protected]','Hello')Code language: Python (python)

As mentioned in the module tutorial, the import * is not a good practice and often leads to bugs. However, you still can utilize it by using a package.

First, create a package called mail with the __init__.py file and create the email.py module in the mail package:

├── mail
|  ├── email.py
|  └── __init__.py
└── main.pyCode language: Python (python)

Second, place the following code in the email.py file:

# email.py

__all__ = ['send']


def send(email, message):
    print(f'Sending "{message}" to {email}')


def attach_file(filename):
    print(f'Attach {filename} to the message')Code language: Python (python)

Third, use the import * and add the send() function to the __all__ variable in the __init__.py:

from .email import * 

__all__ = email.__all__Code language: Python (python)

By doing this, the mail package exposes only the send() function specified in the email.__all__ variable. It hides the attach_file() from the outside.

From the main.py file, you can import the mail package and use the send() function like this:

# main.py

import mail


mail.send('[email protected]','Hello')Code language: Python (python)

Alternative, you can import the send() function from the mail package:

# main.py

from mail import send


send('[email protected]','Hello')Code language: Python (python)

Summary

To make a function private in Python:

  • First, create a package with the __init__.py file
  • Second, do not specify the function in the __all__ variable.
  • Third, import all symbols from the module in the __init__.py file of the package and expose only the public functions by using the __all__ variable.
Did you find this tutorial helpful ?