os.path
funktioniert auf lustige Weise. Es sieht so aus, als os
sollte es ein Paket mit einem Submodul sein path
, aber in Wirklichkeit os
ist es ein normales Modul, mit dem man magisch sys.modules
injizieren kann os.path
. Folgendes passiert:
Beim Start von Python werden eine Reihe von Modulen geladen sys.modules
. Sie sind nicht an Namen in Ihrem Skript gebunden, aber Sie können auf die bereits erstellten Module zugreifen, wenn Sie sie auf irgendeine Weise importieren.
sys.modules
ist ein Diktat, in dem Module zwischengespeichert werden. Wenn Sie ein Modul importieren und es bereits irgendwo importiert wurde, wird die Instanz in gespeichert sys.modules
.
os
gehört zu den Modulen, die beim Start von Python geladen werden. Es weist sein path
Attribut einem os-spezifischen Pfadmodul zu.
Es wird injiziert, sys.modules['os.path'] = path
so dass Sie " import os.path
" tun können, als wäre es ein Submodul.
Ich neige dazu, mich os.path
als ein Modul vorzustellen, das ich verwenden möchte, anstatt als etwas im os
Modul . Obwohl es nicht wirklich ein Submodul eines Pakets namens ist os
, importiere ich es so, wie es eines ist, und das tue ich immerimport os.path
. Dies steht im Einklang mit der os.path
Dokumentation.
Übrigens führt diese Art von Struktur meiner Meinung nach zu einer frühen Verwirrung vieler Python-Programmierer über Module und Pakete sowie über die Code-Organisation. Das hat wirklich zwei Gründe
Wenn Sie sich os
ein Paket vorstellen und wissen, dass Sie import os
auf das Submodul zugreifen können os.path
, werden Sie möglicherweise später überrascht, wenn Sie dies nicht tun import twisted
und automatisch zugreifen können, twisted.spread
ohne es zu importieren.
Es ist verwirrend, dass dies os.name
eine normale Sache ist, eine Zeichenfolge und os.path
ein Modul. Ich strukturiere meine Pakete immer mit leeren __init__.py
Dateien, so dass ich auf der gleichen Ebene immer eine Art von Dingen habe: ein Modul / Paket oder anderes Zeug. Mehrere große Python-Projekte verfolgen diesen Ansatz, wodurch tendenziell strukturierterer Code erstellt wird.
import os.path
selbst und denke, das ist ein schöner Weg. Mit "Dies steht im Einklang mit der Dokumentation von os.path " habe ich gemeint, dass es in der Dokumentation unter docs.python.org/library/os.path.html eine eigene Seite erhält .os.py
spritzt tatsächlich hineinsys.modules['os.path']
. Deshalbfrom os.path import something
funktioniert das eigentlich. Ich war neugierig, wann dies eingeführt wurde und überprüfte die Quelle. Unterhaltsame Tatsache: Dies ist aus dem Jahr 1999, erstmals in Python 1.5.2 enthalten. Das ursprüngliche Commit ist hier .Gemäß PEP-20 von Tim Peters sind "Explizit besser als implizit" und "Lesbarkeit zählt". Wenn alles, was Sie vom
os
Modul benötigen, unter istos.path
,import os.path
wäre es expliziter und lassen Sie andere wissen, was Sie wirklich interessiert.Ebenso sagt PEP-20 auch "Einfach ist besser als komplex". Wenn Sie also auch Dinge benötigen, die sich unter dem allgemeineren
os
Dach befinden,import os
wäre dies vorzuziehen.quelle
import os
es wirklich darum geht, auf irgendeine sinnvolle Weise "einfach" zu sein. Einfach! = Kurz.import os
und einimport os.path
ist dumm, wenn Sie zB brauchenos.getcwd()
undos.path.isfile()
Endgültige Antwort:
import os
und verwendenos.path
. nichtimport os.path
direkt.Aus der Dokumentation des Moduls selbst:
quelle
os.path
Modul handelt, das nicht vorhanden ist, sondern fürposixpath
."Instead of importing this module directly, import os and refer to this module as os.path."
befindet sich inposixpath.py
(odermacpath.py
,ntpath.py
etc.). Ich bin mir ziemlich sicher, dass sie bedeuten, dass manimport posixpath
das Modul nicht (was funktioniert) über importieren sollte,os
um eine bessere Portabilität zu erreichen. Ich glaube nicht, dass sie eine Empfehlung geben wollen, ob sie bevorzugt werdenimport os
oder nichtimport os.path
.Interessanterweise werden beim Importieren von os.path alle Betriebssysteme importiert. Versuchen Sie Folgendes in der interaktiven Eingabeaufforderung:
Das Ergebnis ist das gleiche, als hätten Sie gerade das Betriebssystem importiert. Dies liegt daran, dass os.path je nach Betriebssystem auf ein anderes Modul verweist. Python importiert daher os, um zu bestimmen, welches Modul für den Pfad geladen werden soll.
Referenz
Bei einigen Modulen wird das Sprichwort
import foo
nicht angezeigtfoo.bar
, daher hängt es wohl wirklich vom Design des jeweiligen Moduls ab.Im Allgemeinen sollte der Import der benötigten expliziten Module geringfügig schneller sein. Auf meiner Maschine:
import os.path
:7.54285810068e-06
Sekundenimport os
:9.21904878972e-06
SekundenDiese Zeiten sind nahe genug, um vernachlässigbar zu sein. Ihr Programm muss möglicherweise ab
os
sofort oder zu einem späteren Zeitpunkt andere Module verwenden. Daher ist es normalerweise sinnvoll, nur die zwei Mikrosekunden zu opfern undimport os
diesen Fehler zu einem späteren Zeitpunkt zu vermeiden. Normalerweise importiere ich nur das Betriebssystem als Ganzes, kann aber sehen, warum einige es vorziehenimport os.path
, technisch effizienter zu sein und den Lesern des Codes zu vermitteln, dass dies der einzige Teil desos
Moduls ist, der verwendet werden muss. Es läuft im Wesentlichen auf eine Stilfrage in meinem Kopf hinaus.quelle
from os import path
macht die Aufrufe zum Pfad noch schneller, wenn Geschwindigkeit das Problem ist.Der gesunde Menschenverstand funktioniert hier:
os
ist ein Modul undos.path
ist auch ein Modul. Importieren Sie einfach das Modul, das Sie verwenden möchten:Wenn Sie Funktionen im
os
Modul verwenden möchten , importieren Sieos
.Wenn Sie Funktionen im
os.path
Modul verwenden möchten , importieren Sieos.path
.Wenn Sie Funktionen in beiden Modulen verwenden möchten, importieren Sie beide Module:
Als Referenz:
Lib / idlelib / rpc.py verwendet
os
und importiertos
.Lib / idlelib / idle.py verwendet
os.path
und importiertos.path
.Lib / surepip / init .py verwendet beide und importiert beide.
quelle
Es konnte keine endgültige Referenz gefunden werden, aber ich sehe, dass der Beispielcode für os.walk os.path verwendet, aber nur os importiert
quelle