Приватные методы в Python
В этом уроке вы узнаете, как определять приватные методы в Python в модуле и сделать с помощью переменной __all__.
Предположим, у вас есть модуль mail.py с двумя функциями send() и Attach_file().
def send(email, message): print(f'Sending "{message}" to {email}') def attach_file(filename): print(f'Attach {filename} to the message')
И вы хотите предоставить другим модулям только функцию send(), а не функцию Attach_file(). Другими словами, вы хотите, чтобы функция Attach_file() была частной и не была доступна вне модуля mail.
Обратите внимание, что для простоты мы распечатываем только часть текста в функциях.
Если другие модули используют оператор import * следующим образом:
from mail import *
вы можете добавить к имени функции знак подчеркивания(_), чтобы сделать его приватным. Например:
def send(email, message): print(f'Sending "{message}" to {email}') def _attach_file(filename): print(f'Attach {filename} to the message')
Из файла mail.py вы можете использовать модуль import * from mail и видеть только функцию send():
from mail import * send('[email protected]','Hello')
Другими словами, вы не сможете получить доступ к функции _attach_file() из основного модуля. Если вы попытаетесь вызвать функцию _attach_file(), вы получите ошибку.
Другой способ сделать функцию Attach_file() приватной — использовать переменную __all__. Таким образом, вам не нужно добавлять к имени функции подчеркивание(_), чтобы сделать его частным.
__all__ определяет список функций (а также переменных и других объектов), доступных другим модулям. Другими словами, вы можете сделать функцию частной, не указывая ее в переменной __all__.
В следующем примере используется переменная __all__ в модуле mail, чтобы сделать функцию send() общедоступной, а функцию Attach_file() — частной:
# 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')
Из модуля main.py вы также не можете получить доступ к функции Attach_file(), как раньше:
# main.py from mail import * send('[email protected]','Hello')
Как упоминалось в руководстве по модулю, import * не является хорошей практикой и часто приводит к ошибкам. Тем не менее, вы все равно можете использовать его, применив package.
- Сначала создайте пакет под названием mail с файлом __init__.py и создайте модуль email.py в почтовом пакете:
├── mail | ├── email.py | └── __init__.py └── main.py
- Во-вторых, поместите следующий код в файл email.py:
# 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')
- В-третьих, используйте import * и добавьте функцию send() в переменную __all__ в __init__.py:
from .email import * __all__ = email.__all__
При этом почтовый пакет предоставляет только функцию send(), указанную в переменной email.__all__. Он скрывает Attach_file() снаружи.
Из файла main.py вы можете импортировать почтовый пакет и использовать функцию send() следующим образом:
# main.py import mail mail.send('[email protected]','Hello')
Альтернативно вы можете импортировать функцию send() из почтового пакета:
# main.py from mail import send send('[email protected]','Hello')