Должен ли я использовать `import os.path` или` import os`? - PullRequest
127 голосов
/ 27 апреля 2010

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

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

Или ...

# Is importing os enough?
import os

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

Ответы [ 7 ]

146 голосов
/ 28 апреля 2010

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

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

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

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

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


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

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

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

29 голосов
/ 28 апреля 2010

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

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

15 голосов
/ 26 апреля 2013

Окончательный ответ: 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).
...
6 голосов
/ 27 апреля 2010

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

import os.path
dir(os)

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

ссылка

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


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

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

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

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

4 голосов
/ 06 сентября 2018

Здесь работает здравый смысл: os - это модуль, и os.path - это тоже модуль. Поэтому просто импортируйте модуль, который вы хотите использовать:

  • Если вы хотите использовать функциональные возможности в модуле os, то импортируйте os.

  • Если вы хотите использовать функциональные возможности в модуле os.path, то импортируйте os.path.

  • Если вы хотите использовать функциональные возможности в обоих модулях, импортируйте оба модуля:

    import os
    import os.path
    

Для справки:

4 голосов
/ 27 апреля 2010

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

0 голосов
/ 26 июля 2016

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

Я думаю

import os в порядке.

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

os.path()

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

os.path.exists()
...