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.py
Code 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.