Должен ли я использовать `import os.path` или` import os`?

Согласно официальной документации , os.path является модулем. Таким образом, каков предпочтительный способ его импорта?

# Should I always import it explicitly?
import os.path

Или...

# Is importing os enough?
import os

Пожалуйста, НЕ отвечайте: "Импорт os работает для меня". Я знаю, это работает для меня тоже прямо сейчас (с Python 2.6). То, что я хочу знать, - это официальная рекомендация по этому вопросу. Итак, если вы ответите на этот вопрос, разместите свои ссылки.

Ответ 1

os.path работает смешно. Похоже, что os должен быть пакетом с подмодулем path, но на самом деле os является нормальным модулем, который делает магию с sys.modules для ввода os.path. Вот что происходит:

  • Когда Python запускается, он загружает кучу модулей в sys.modules. Они не привязаны к каким-либо именам в вашем script, но вы можете получить доступ к уже созданным модулям, когда вы их каким-то образом импортируете.

    • sys.modules - это dict, в котором модули кэшируются. Когда вы импортируете модуль, если он уже был где-то импортирован, он получает экземпляр, хранящийся в sys.modules.
  • os входит в число модулей, загружаемых при запуске Python. Он присваивает свой атрибут path модулю пути os-specific.

  • Он вводит sys.modules['os.path'] = path, чтобы вы могли сделать "import os.path", как если бы это был подмодуль.

Я склонен думать о os.path как о модуле, который я хочу использовать, а не о вещи в модуле os, поэтому, хотя это не действительно подмодуль пакета с именем os, я импортирую его как как и один и , я всегда делаю import os.path. Это согласуется с тем, как документируется os.path.


Кстати, такая структура приводит к большому запуску ранних путаниц программистов Python о модулях и пакетах и ​​организации кода, я думаю. Это действительно по двум причинам.

  • Если вы думаете о os как о пакете и знаете, что можете сделать import os и иметь доступ к подмодулю os.path, вы можете быть удивлены позже, когда вы не можете сделать import twisted и автоматически перейдите в twisted.spread, не импортируя его.

  • Запутано, что os.name - это нормальная вещь, строка и os.path - это модуль. Я всегда структурирую свои пакеты с пустыми __init__.py файлами, так что на одном уровне у меня всегда есть один тип вещи: модуль/пакет или другой материал. Несколько больших проектов Python используют этот подход, который, как правило, создает более структурированный код.

Ответ 2

В соответствии с PEP-20 Тимом Петерсом: "Явный лучше, чем неявный" и "Чтение счетчиков". Если все, что вам нужно от модуля os, находится под os.path, import os.path будет более явным и пусть другие знают, что вас действительно волнует.

Аналогично, PEP-20 также говорит: "Простой лучше, чем сложный", поэтому, если вам также нужен материал, который находится под более общим зонтиком os, предпочтительнее import os.

Ответ 3

Окончательный ответ: import os и используйте os.path. прямо не import os.path.

Из документации самого модуля:

>>> import os
>>> help(os.path)
...
Instead of importing this module directly, import os and refer to
this module as os.path.  The "os.path" name is an alias for this
module on Posix systems; on other systems (e.g. Mac, Windows),
os.path provides the same operations in a manner specific to that
platform, and is an alias to another module (e.g. macpath, ntpath).
...

Ответ 4

Интересно, что импорт os.path будет импортировать все os. попробуйте следующее в интерактивной подсказке:

import os.path
dir(os)

Результат будет таким же, как если бы вы только что импортировали os. Это связано с тем, что os.path будет ссылаться на другой модуль, на основе которого у вас есть операционная система, поэтому python будет импортировать os для определения того, какой модуль загружается для пути.

ссылка

С некоторыми модулями, говоря import foo, не будет отображаться foo.bar, поэтому я думаю, что это действительно зависит от дизайна конкретного модуля.


В общем, просто импортировать явные модули, которые вам нужны, должны быть немного быстрее. На моей машине:

import os.path : 7.54285810068e-06 секунды

import os : 9.21904878972e-06 секунды

Эти времена достаточно близки, чтобы быть довольно незначительными. Возможно, вашей программе придется использовать другие модули из os либо сейчас, либо позже, поэтому обычно бывает полезно просто пожертвовать двумя микросекундами и использовать import os, чтобы избежать этой ошибки позднее. Обычно я просто импортирую ОС в целом, но могу понять, почему некоторые предпочитают import os.path технически быть более эффективными и передавать читателям кода, который является единственной частью модуля os, который должен быть используемый. Это, по сути, сводится к вопросу стиля в моем сознании.

Ответ 5

Не удалось найти какую-либо окончательную ссылку, но я вижу, что код примера для os.walk использует os.path, но только импортирует os

Ответ 6

Я согласен с Майком

Я думаю,

import os отлично.

Вы просто должны упомянуть о таких деталях

os.path()

или если вы вызываете модуль в модуле

os.path.exists()