web-dev-qa-db-fra.com

Devrais-je utiliser `import os.path` ou` import os`?

Selon le documentation officielle , os.path est un module. Ainsi, quel est le moyen privilégié de l’importer?

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

Ou...

# Is importing os enough?
import os

Ne répondez pas s'il vous plaît "importer os fonctionne pour moi". Je sais, cela fonctionne aussi pour moi aussi maintenant (à partir de Python 2.6). Ce que je veux savoir, c'est une recommandation officielle à ce sujet. Donc, si vous répondez à cette question, veuillez publiez vos références .

129
Denilson Sá Maia

os.path Fonctionne de manière amusante. Il semble que os devrait être un paquet avec un sous-module path, mais en réalité, os est un module normal qui fait de la magie avec sys.modules Pour injecter os.path. Voici ce qui se passe:

  • Lorsque Python démarre, il charge un tas de modules dans sys.modules. Ils ne sont liés à aucun nom dans votre script, mais vous pouvez accéder aux modules déjà créés lorsque vous les importez d'une certaine manière.

    • sys.modules Est un dict dans lequel les modules sont mis en cache. Lorsque vous importez un module, s'il a déjà été importé quelque part, l'instance est stockée dans sys.modules.
  • os fait partie des modules chargés lorsque Python démarre. Il attribue son attribut path à un module de chemin d'accès spécifique au système d'exploitation.

  • Il injecte sys.modules['os.path'] = path Pour que vous puissiez faire "import os.path" Comme s'il s'agissait d'un sous-module.

J'ai tendance à penser à os.path Comme un module que je veux utiliser plutôt que une chose dans le module os, donc même si ce n'est pas vraiment un sous-module d'un paquetage appelé os, je l'importe un peu comme si c'était un et je fais toujours import os.path. Ceci est cohérent avec la façon dont os.path Est documenté.


Incidemment, ce type de structure entraîne beaucoup de confusion chez les programmeurs Python) à propos des modules et des packages et de l'organisation du code, je pense. C'est vraiment pour deux raisons

  1. Si vous pensez que os est un paquet et que vous savez que vous pouvez faire import os Et avoir accès au sous-module os.path, Vous serez peut-être surpris plus tard lorsque vous ne pourrez pas faire import twisted Et accédez automatiquement à twisted.spread Sans l'importer.

  2. Il est déroutant que os.name Soit une chose normale, une chaîne et que os.path Soit un module. Je structure toujours mes paquets avec des fichiers __init__.py Vides, de sorte qu'au même niveau, j'ai toujours un type de chose: un module/paquet ou autre. Plusieurs grands Python projets adoptent cette approche, ce qui tend à créer du code plus structuré.

148
Mike Graham

Selon PEP-2 de Tim Peters, "Explicit est meilleur qu'implicite" et "La lisibilité compte". Si tout ce dont vous avez besoin du module os est sous os.path, import os.path serait plus explicite et ferait savoir aux autres ce qui compte vraiment pour vous.

De même, PEP-20 dit aussi "Simple, c'est mieux que complexe", donc si vous avez besoin d'éléments qui se trouvent sous le para-général plus général os, import os serait préférable.

29
Nick T

Réponse définitive: import os et utilise os.path. ne pas import os.path directement.

De la documentation du module lui-même:

>>> 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).
...
16
lesmana

Chose intéressante, importer os.path importera tous les os. essayez ce qui suit dans l'invite interactive:

import os.path
dir(os)

Le résultat sera le même que si vous venez d'importer os. Cela est dû au fait que os.path fera référence à un module différent en fonction de votre système d'exploitation. Par conséquent, python importera os pour déterminer le module à charger pour le chemin d'accès.

référence

Avec certains modules, dire que import foo N'exposera pas foo.bar, Je suppose donc que cela dépend vraiment de la conception du module spécifique.


En général, le simple fait d'importer les modules explicites dont vous avez besoin devrait être légèrement plus rapide. Sur ma machine:

import os.path: 7.54285810068e-06 Secondes

import os: 9.21904878972e-06 Secondes

Ces temps sont assez proches pour être assez négligeables. Votre programme devra peut-être utiliser d'autres modules de os soit maintenant, soit plus tard. Il est donc généralement logique de sacrifier les deux microsecondes et d'utiliser import os Pour éviter cette erreur ultérieurement. . Habituellement, je ne fais qu'importer le système d'exploitation dans son ensemble, mais je comprends pourquoi certains préféreraient que import os.path Soit techniquement plus efficace et indique aux lecteurs du code que c'est la seule partie du os module qui devra être utilisé. Cela se résume essentiellement à une question de style dans mon esprit.

6
Matt Boehm

Le bon sens fonctionne ici: os est un module et os.path est également un module. Alors, importez simplement le module que vous souhaitez utiliser:

  • Si vous souhaitez utiliser les fonctionnalités du module os, alors importez os.

  • Si vous souhaitez utiliser les fonctionnalités du os.path module, puis importer os.path.

  • Si vous souhaitez utiliser des fonctionnalités dans les deux modules, importez les deux modules:

    import os
    import os.path
    

Pour référence:

4
Cyker

Impossible de trouver une référence définitive, mais je vois que l'exemple de code pour os.walk utilise os.path mais importe uniquement os

4
Chris Hulan