Seite 1 von 1
Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 08:56
von patmaster
Hi zusammen,
ich habe ein ZIP-Archiv das eine Ordnerstruktur und weitere Archive enthält.
Nun will ich nur bestimmte Archive entpacken, was auch wunderbar klappt mit diesem Code:
Code: Alles auswählen
import glob, zipfile
for file in glob.glob("R:\\Produktion\\Cases\\input\\*.xml"):
filename = str(os.path.split(file)[1]).replace('.xml', '.zip')
ziplist = zipfile.ZipFile("E:\\20110510.zip", "r")
for member in zipfile.ZipFile.namelist(ziplist):
if str(member).__contains__(filename):
ziplist.extract(member, "E:\\")
Es werden zwar die richtigen files extrahiert, nur leider wird auch die Ordnerstruktur für die files angelegt.
Kann ich das iwie verhindern ?!
Re: Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 10:08
von BlackJack
@patmaster: Da liegt aber ein bisschen was im Argen was das Verständnis von Python angeht. Und die Namensgebung ist auch nicht besonders gut.
`file` ist der Name eines eingebauten Typs, den sollte man nicht an etwas anderes binden. Zudem das was `glob()` liefert ja gar keine Datei-Objekte sind, sondern Zeichenketten die Pfade darstellen.
Sämtliche `str()`-Aufrufe in dem Quelltextschnippsel sollten überflüssig sein, weil es sich bei den Argumenten bereits um Zeichenketten handelt.
Der `replace()`-Aufruf auf dem Dateinamen kann Probleme bereiten, wenn '.xml' nicht nur als Endung, sondern auch *im* Namen vorkommt.
`ziplist` ist ein irreführender Name, weil es sich gar nicht um eine Liste, sondern um ein `ZipFile`-Objekt handelt.
Was soll ``zipfile.ZipFile.namelist(ziplist)``? Warum rufst Du da nicht die Methode auf `ziplist` auf? Und warum verwendest Du bei ``str(member).__contains__(filename)`` nicht den ``in``-Operator? Die ”magischen” Methoden sollte man eigentlich nur direkt aufrufen, wenn es keine andere Möglichkeit gibt. Wobei ``in`` genau wie bei dem `replace()` Probleme bereiten kann. Du willst ja nicht wissen ob der Name irgendwo *in* dem Pfad vorkommt, sondern ob er damit *endet*. Dann solltest Du auch nur das überprüfen.
Zum Pfad-Problem: Da wirst Du das auslesen aus dem Archiv und das schreiben in eine Datei selber implementieren müssten.
Re: Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 10:23
von patmaster
Ich habe erst vor kurzem mit Python begonnen. Da ich es aber schon einsetzen muss/will pfusche ich da noch etwas.
das file auch ein typ ist war mir nicht bekannt.
Diese casterei mit String mach ich irgendwie immer zur Sicherheit...stimmt könnte ich lassen.
Ich bin mir sicher das im file namen nirgends "xml" vorkommt, sonst hätte ich das natürlich anders gelöst.
ziplist heißt es weil es mal ne Liste war...hätte ich umbenennen sollen.
Warum ich die Methode nicht gleich aus ziplist aufrufe ist mir auch grad schleierhaft...echt weird.
Der in-Operator war mir noch nicht bekannt.
Danke für die ganzen Tipps

Re: Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 10:50
von BlackJack
@patmaster: Deswegen sollte man möglichst vermeiden konkrete Typen im Namen zu erwähnen. Wenn man den Typen mal ändert, muss man auch den Namen überall anpassen, oder man hat einen irreführenden Namen im Programm. Ungetestet:
Code: Alles auswählen
import os
from glob import glob
from zipfile import ZipFile
CASES_PATH = r'R:\Produktion\Cases\input'
ARCHIVE_PATH = r'E:\20110510.zip'
EXTRACT_PATH = r'E:'
for path in glob(os.path.join(CASES_PATH, '*.xml')):
filename = os.path.splitext(os.path.basename(path))[0] + '.zip'
zip_file = ZipFile(ARCHIVE_PATH)
for member in zip_file.namelist():
if member.endswith(filename):
data = zip_file.read(name)
with open(os.path.join(EXTRACT_PATH, filename), 'wb') as out_file:
out_file.write(data)
break
Wobei mir der Algorithmus etwas ineffizient vorkommt. Für jede XML-Datei wird immer linear die Namensliste des ZIP-Archivs eingelesen und durchsucht.
Re: Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 11:02
von patmaster
Ich war gerade noch am Doku lesen da hattest du es schon fertig ^^
Funzt wunderbar....Vielen Dank !
Einziger Fehler
muss
heissen
Darf man fragen warum du "splitext" und "basename" statt "split" verwendest ?!
Re: Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 12:07
von BlackJack
@patmaster: `splitext()` und `basename()` machen genau das was man an der Stelle braucht. Warum sollte man sie nicht verwenden? `splitext()` kann man gar nicht durch `os.path.split()` ersetzen, und ``os.path.basename(p)`` sagt IMHO verständlicher was da passiert, als ``os.path.split(p)[1]``. Insbesondere für Leute die wissen was das Unix-Kommando ``basename`` macht.
Re: Frage zu Zipfile
Verfasst: Dienstag 19. Juli 2011, 13:28
von patmaster
Ich seh schon das du dir das replace später ersparst weil du den filenamen ohne extension bekommst...hatte ich vorher nicht gerafft.
Is mir gerade aufgefallen auf python.org:
Note that the result of this function is different from the Unix basename program; where basename for '/foo/bar/' returns 'bar', the basename() function returns an empty string ('').
Hast du vermutlich gewusst aber ich dachte ich poste es...
Danke noch mal für die Hilfe !
Re: Frage zu Zipfile
Verfasst: Mittwoch 20. Juli 2011, 09:22
von lunar
@patmaster: In diesem Fall ist das irrelevant, da man durch die Art des "glob()" sicher sein kann, dass keine Schrägstriche am Ende stehen. Ansonsten kann man Pfade mit "os.path.normpath()" in eine normalisierte Darstellung umwandeln, in der keine Schrägstriche am Ende stehen.