Я кодирую небольшой модуль Python, состоящий из двух частей:
- некоторые функции, определяющие публичный интерфейс,
- класс реализации, используемый вышеуказанными функциями, но не имеющий смысла вне модуля.
Сначала я решил «спрятать» этот класс реализации, определив его внутри функции, использующей его, но это затрудняет читаемость и не может использоваться, если несколько функций повторно используют один и тот же класс.
Итак, помимо комментариев и строк документации, существует ли механизм, позволяющий пометить класс как «частный» или «внутренний»? Я знаю о механизме подчеркивания, но насколько я понимаю, он применяется только к именам переменных, функций и методов.
источник
Коротко:
Вы не можете обеспечить конфиденциальность . В Python нет частных классов / методов / функций. По крайней мере, не строгая конфиденциальность, как в других языках, например Java.
Вы можете только указать / предложить конфиденциальность . Это следует соглашению. Соглашение python для обозначения класса / функции / метода как закрытого заключается в том, чтобы предварять его знаком _ (подчеркивание). Например,
def _myfunc()
илиclass _MyClass:
. Вы также можете создать псевдо-конфиденциальность, поставив перед методом два символа подчеркивания (например:)__foo
. Вы не можете получить доступ к методу напрямую, но вы все равно можете вызвать его через специальный префикс, используя имя класса (например:)_classname__foo
. Поэтому лучшее, что вы можете сделать, - это указать / предложить конфиденциальность, а не обеспечивать ее соблюдение.В этом отношении Python похож на Perl. Перефразируя известную фразу о конфиденциальности из книги Perl, философия заключается в том, что вы должны держаться подальше от гостиной, потому что вас не пригласили, а не потому, что она защищена дробовиком.
Чтобы получить больше информации:
источник
Определите
__all__
список имен, которые вы хотите экспортировать ( см. Документацию ).источник
Иногда я использую такой шаблон:
Определите класс:
Создайте экземпляр класса, перезаписав имя класса:
Определите символы, раскрывающие функциональность:
Удалите сам экземпляр:
Теперь у вас есть модуль, который предоставляет только ваши общедоступные функции.
источник
По соглашению перед внутренними классами, функциями и переменными добавляется "_".
источник
Чтобы обратиться к проблеме соглашений о дизайне, и, как сказал Кристофер, на самом деле в Python не существует такого понятия, как «частный». Это может показаться странным для кого-то, кто имеет опыт работы с C / C ++ (например, я некоторое время назад), но в конечном итоге вы, вероятно, поймете, что следующих соглашений достаточно.
Видеть что-то с подчеркиванием впереди должно быть достаточно хорошим намеком, чтобы не использовать это напрямую. Если вас беспокоит загромождение
help(MyClass)
вывода (это то, на что все смотрят при поиске того, как использовать класс), подчеркнутые атрибуты / классы туда не включаются, так что вы в конечном итоге просто получите описание своего «общедоступного» интерфейса.Кроме того, у всего публичного есть свои потрясающие преимущества, например, вы можете модульно тестировать практически все что угодно извне (чего вы не можете сделать с частными конструкциями C / C ++).
источник
Используйте два символа подчеркивания для префикса имен «частных» идентификаторов. Для классов в модуле используйте одинарное подчеркивание в начале, и они не будут импортированы с использованием «from module import *».
(В Python нет такой вещи, как истинный «частный». Например, Python просто автоматически изменяет имена членов класса с двойным подчеркиванием, чтобы быть
__clssname_mymember
. Так что на самом деле, если вы знаете искаженное имя, вы все равно можете использовать «частный» объект . См. Здесь. И, конечно, вы можете вручную импортировать «внутренние» классы, если хотите).источник