Подтвердить что ты не робот

Модуль Python: 'Private' в пакете

У меня есть пакет mypack с модулями mod_a и mod_b. Я сам намерен сам пакет и mod_a импортировать:

import mypack
import mypack.mod_a

Однако я хотел бы сохранить mod_b для эксклюзивного использования mypack. Это потому, что существует просто для организации последнего внутреннего кода.

Мой первый вопрос: есть ли принятая практика в программировании на Python иметь модули 'private', подобные этому?

Если да, то мой второй вопрос: какой лучший способ передать это намерение клиенту? Я префикс имени с подчеркиванием (т.е. _mod_b)? Или было бы неплохо объявить подпакет private и разместить там все такие модули?

4b9b3361

Ответ 1

Решение, на котором я остановился, - создать подпакет 'private' и поместить все модули, которые я хочу скрыть там. Таким образом, они остаются убранными, оставляя mypack список модулей чище и легче разбираться.

Для меня это тоже не выглядит неряшливым.

Ответ 2

I префикс частных модулей с подчеркиванием для передачи намерения пользователю. В вашем случае это будет mypack._mod_b

Это в том же духе (но не полностью аналогичном) рекомендации PEP8 для обозначения модулей расширения C с лидирующим подчеркиванием при его завершении модулем Python; т.е. _socket и socket.

Ответ 3

Пока нет явных закрытых ключевых слов, существует соглашение о том, что частные функции начинаются с одного символа подчеркивания, но двузначный знак подчеркивания сделает его таким, чтобы другие не могли легко вызвать функцию извне модуля. Смотрите PEP 8

- _single_leading_underscore: weak "internal use" indicator.  E.g. "from M
  import *" does not import objects whose name starts with an underscore.

- single_trailing_underscore_: used by convention to avoid conflicts with
  Python keyword, e.g.

  Tkinter.Toplevel(master, class_='ClassName')

- __double_leading_underscore: when naming a class attribute, invokes name
  mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).

- __double_leading_and_trailing_underscore__: "magic" objects or
  attributes that live in user-controlled namespaces.  E.g. __init__,
  __import__ or __file__.  Never invent such names; only use them
  as documented.

Чтобы сделать весь модуль закрытым, не включайте его __init__.py.

Ответ 4

Python не строго знает или поддерживает "private" или "защищенные" методы или классы. Там есть соглашение о том, что методы с префиксом одного подчеркивания не являются частью официального API, но я бы не делал этого по классам или файлам - это уродливо.

Если кто-то действительно нуждается в подклассе или доступе к mod_b, зачем ему это мешает? Вы всегда можете указать предпочтительный API в своей документации и документе в своем модуле, к которому вы не должны обращаться напрямую, и вместо этого используйте mypack.

Ответ 5

В этом сценарии нужно учитывать одну вещь - косвенный импорт. Если в mypack вы

from mypack._mod_b import foo
foo()

Тогда пользователь может

from mypack import foo
foo()

и не будь мудрее. Я рекомендую импортировать как

from mypack import _mod_b
_mod_b.foo()

тогда пользователь сразу увидит красный флажок при попытке

from mypack import _mod_b

Что касается фактической структуры каталогов, вы можете даже расширить ответ джереми в пакет _package_of_this_kind, где все, что может иметь любые "модификаторы доступа", по вашему желанию - пользователи будут знать, что есть драконы