Also irgendwie verstehe ich das noch nicht...
Es gibt das neue os.scandir(), als ersatz für os.listdir(): https://docs.python.org/3/library/os.html#os.scandir
os.scandir() spuckt das neue os.DirEntry() instanzen aus...
Das alte os.walk() nutzt zwar os.scandir() und hat somit die os.DirEntry() instanzen, liefert aber, wie bei der alten API nur die Pfade, aber nicht die Instanz
Aber das wäre doch hilfreich...
Was tun? Den code von os.walk() duplizieren und abändern, damit er os.DirEntry() instanzen auswirft?!?
Ist doch auch doof.
Dann gibt es das neue pathlib.Path()... Könnte ja ebenfalls bei os.walk() Verwendung finden...
Ist ein os.walk2() oder so, in mache?!? Der dann das alles "Verbindet" ?
Python 3.5: os.walk(), os.scandir() und os.DirEntry
Nicht, dass ich wüsste. Aber du kannst ein rekursives `scandir()` relativ leicht selbst implementieren:jens hat geschrieben:Ist ein os.walk2() oder so, in mache?!? Der dann das alles "Verbindet" ?
Code: Alles auswählen
def scantree(path):
"""Recursively yield DirEntry objects for given directory."""
for entry in scandir(path):
if entry.is_dir(follow_symlinks=False):
yield from scantree(entry.path)
else:
yield entry
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Hm! Hab was dummes gefunden... Zumindest für Windows
Unter Windows gibt es ja die Katastrophe mit den "Schein Verzeichnissen". Damit alte Programme in alten Pfaden schreiben können, diese aber auf neue Pfade umgeleitet werden usw...
Heißen Junction und meinen wohl sowas wie symlinks
Kann man in der cmd.exe sich z.B. so anzeigen lassen:
Ein os.walk() ignoriert diese (Selbst bei followlinks=True)...
Ein os.scandir() allerdings nicht
Das dumme: C:\Users\jens\AppData\Local\Anwendungsdaten zeigt auf: C:\Users\jens\AppData\Local
Also eine schöne verschachtelte Endlosschleife, wenn man da mit os.scandir() rekursiv durchwandert
Zum selbst probieren: os.walk() listet u.a. Anwendungsdaten nicht:
Mit os.scandir():
Listet u.a.: <DirEntry 'Anwendungsdaten'>, <DirEntry 'Temporary Internet Files'> und <DirEntry 'Verlauf'> auf...
Dabei ist ein entry.is_symlink() immer False
Aber auch os.path.islink(entry.path) liefert immer False
Also os.walk() versucht eigentlich auch in der Verzeichnis wie C:\Users\jens\AppData\Local\Anwendungsdaten rein zu gehen... Aber das anschließende os.listdir() schlägt fehl... Sieht man aber erstmal nicht, aber so:
Liefert dann:
Unter Windows gibt es ja die Katastrophe mit den "Schein Verzeichnissen". Damit alte Programme in alten Pfaden schreiben können, diese aber auf neue Pfade umgeleitet werden usw...
Heißen Junction und meinen wohl sowas wie symlinks
Kann man in der cmd.exe sich z.B. so anzeigen lassen:
Code: Alles auswählen
C:\>cd /d %LOCALAPPDATA%
C:\Users\jens\AppData\Local>dir /al
Datenträger in Laufwerk C: ist Win10 1
Volumeseriennummer: 9E8F-2FF3
Verzeichnis von C:\Users\jens\AppData\Local
18.01.2016 08:52 <JUNCTION> Anwendungsdaten [C:\Users\jens\AppData\Local]
18.01.2016 08:52 <JUNCTION> Temporary Internet Files [C:\Users\jens\AppData\Local\Microsoft\Windows\INetCache]
18.01.2016 08:52 <JUNCTION> Verlauf [C:\Users\jens\AppData\Local\Microsoft\Windows\History]
0 Datei(en), 0 Bytes
3 Verzeichnis(se), 19.210.612.736 Bytes frei
Ein os.scandir() allerdings nicht
Das dumme: C:\Users\jens\AppData\Local\Anwendungsdaten zeigt auf: C:\Users\jens\AppData\Local
Also eine schöne verschachtelte Endlosschleife, wenn man da mit os.scandir() rekursiv durchwandert
Zum selbst probieren: os.walk() listet u.a. Anwendungsdaten nicht:
Code: Alles auswählen
for root, dirs, files in os.walk(os.environ["LOCALAPPDATA"], followlinks=True):
print(root)
Mit os.scandir():
Code: Alles auswählen
for entry in os.scandir(os.environ["LOCALAPPDATA"]):
print(entry)
Dabei ist ein entry.is_symlink() immer False
Aber auch os.path.islink(entry.path) liefert immer False
Also os.walk() versucht eigentlich auch in der Verzeichnis wie C:\Users\jens\AppData\Local\Anwendungsdaten rein zu gehen... Aber das anschließende os.listdir() schlägt fehl... Sieht man aber erstmal nicht, aber so:
Code: Alles auswählen
def walk_error(err):
print("Error: %s" % err)
for root, dirs, files in os.walk(os.environ["LOCALAPPDATA"], onerror=walk_error, followlinks=True):
pass
...und deswegen fehlen die...Error: [WinError 5] Zugriff verweigert: 'C:\\Users\\jens\\AppData\\Local\\Anwendungsdaten'
Error: [WinError 5] Zugriff verweigert: 'C:\\Users\\jens\\AppData\\Local\\Microsoft\\Windows\\INetCache\\Content.IE5'
Error: [WinError 5] Zugriff verweigert: 'C:\\Users\\jens\\AppData\\Local\\Microsoft\\Windows\\Temporary Internet Files'
Error: [WinError 5] Zugriff verweigert: 'C:\\Users\\jens\\AppData\\Local\\Temporary Internet Files'
Error: [WinError 5] Zugriff verweigert: 'C:\\Users\\jens\\AppData\\Local\\Verlauf'
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Als test fällt mir nicht viel ein, außer pathlib.Path().resolve() zu nutzten, denn der Pfad C:\Users\jens\AppData\Local\Anwendungsdaten wird dabei zu: C:\Users\jens\AppData\Local
Also sowas:
Liefert dann u.a.:
Also sowas:
Code: Alles auswählen
def resolveable(path):
path = pathlib.Path(path)
test = path.resolve()
return path == test
for entry in os.scandir(os.environ["LOCALAPPDATA"]):
print(entry, resolveable(entry.path))
Code: Alles auswählen
<DirEntry 'Adobe'> True
<DirEntry 'Anwendungsdaten'> False
<DirEntry 'Autodesk'> True
...
<DirEntry 'Temp'> True
<DirEntry 'Temporary Internet Files'> False
<DirEntry 'Thunderbird'> True
<DirEntry 'TileDataLayer'> True
<DirEntry 'Verlauf'> False
<DirEntry 'VirtualStore'> True
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Was mir auch gerade mal so auffällt, ist die schlechte "integration" von pathlib
Also das geht nicht:
Es gibt zwar ein Path.unlink() und ein Path.symlink_to() aber keinen Ersatz für os.link()
Und weil .path erst mit 3.4.5 und 3.5.2 aufgenommen wurde (s. https://docs.python.org/3/library/pathl ... ePath.path ), kann man nicht das machen:
Also, wenn man ältere Versionen unterstützen möchte, dann geht nur das:
Was komisch wirkt.
EDIT: Wobei ich mich gerade frage, ob ich nicht auch auf den support von <3.4.5 und <3.5.2 verzichten kann?!?
EDIT: Auf keinen Fall 3.5.2 ist ja nichtmal draußen
Also das geht nicht:
Code: Alles auswählen
src = pathlib.Path("/foo/")
dsr = pathlib.Path("/bar/")
os.link(src, dsr)
Und weil .path erst mit 3.4.5 und 3.5.2 aufgenommen wurde (s. https://docs.python.org/3/library/pathl ... ePath.path ), kann man nicht das machen:
Code: Alles auswählen
os.link(src.path, dsr.path)
Code: Alles auswählen
os.link(str(src), str(dsr))
EDIT: Wobei ich mich gerade frage, ob ich nicht auch auf den support von <3.4.5 und <3.5.2 verzichten kann?!?
EDIT: Auf keinen Fall 3.5.2 ist ja nichtmal draußen