@iScream: Vergiss dass es ``global`` gibt und arbeite das Tutorial in der Dokumentation durch.
Die Abfrage von `__name__` kommt für gewöhnlich ganz ans Ende und der ganze Quelltext auf Modulebene sollte in einer Funktion verschwinden. *So* bringt das überhaupt nichts, sondern dient zusammen mit den beiden "Funktionen" und dem ``global`` nur der Verwirrung des Lesers.
`os.chdir()` sollte man IMHO auch gleich wieder vergessen. Das Arbeitsverzeichnis zu ändern ist keine gute Idee, weil man da schnell Probleme bekommt, wenn man das an mehr als einer Stelle machen wollte. Dann weiss man nie so recht wo man gerade ist.
Statt der ersten Schleife könnte man das `glob`-Modul mal anschauen.
Das Du den Text von "verschoben" nach "kopiert" verändert hast ist Blödsinn. Egal was faktisch passiert -- es ist am Ausgangsort hinterher nicht mehr da, dass ist also nicht das was man erwarten würde, wenn das Programm nur meldet, dass kopiert wurde.
Es werden keine Fehler behandelt und der Test vor dem Anlegen eines Verzeichnisses ist überflüssig. Da sollte man einfach versuchen das Verzeichnis anzulegen und eventuelle Fehler dabei ordentlich behandeln. Es können da so nämlich mindestens zwei Dinge passieren: 1. Der Test sagt alles ist okay, und kurz bevor das Verzeichnis angelegt werden soll, macht das ein anderer Prozess, oder 2. es gibt kein Verzeichnis mit dem Namen, aber eine *Datei*. In beiden Fällen haut's Dir eine Ausnahme um die Ohren.
Fotos von Kamera laden und sortieren
Habe das verschwinden lassen Als ich was anderes hier gepostet hatte, war die erste Änderung durch einen anderen dieses "if __name__ ==..." daher ging ich davon aus, damit spart man sich genauso Kritik wie mit konsequentem Englisch. Jetzt kann das "global" doch bleiben, oder? Ich weiß nämlich sonst nicht, wie ich den Wert der Funktion in eine Variable außerhalb verpackt kriege.Die Abfrage von `__name__` kommt für gewöhnlich ganz ans Ende und der ganze Quelltext auf Modulebene sollte in einer Funktion verschwinden. *So* bringt das überhaupt nichts, sondern dient zusammen mit den beiden "Funktionen" und dem ``global`` nur der Verwirrung des Lesers.
Wie sollte ich es wohl vermeiden? Zurzeit sehe ich keinen anderen Weg, an die Bilder zu gelangen (Bitte Vorschlag)`os.chdir()` sollte man IMHO auch gleich wieder vergessen. Das Arbeitsverzeichnis zu ändern ist keine gute Idee, weil man da schnell Probleme bekommt, wenn man das an mehr als einer Stelle machen wollte. Dann weiss man nie so recht wo man gerade ist.
Werde ich mir anschauen. Kenne aber bisher kaum Module, daher helfe ich mir mit "Bordmitteln" (obwohl Module in gewissermaßen auch "Bordmittel" sind)Statt der ersten Schleife könnte man das `glob`-Modul mal anschauen.
Dickes Sorry! Ich hatte den funktionierenden Code noch "verschönert" vor dem posten. Daher war das Löschen nicht auskommentiert - jetzt aberDas Du den Text von "verschoben" nach "kopiert" verändert hast ist Blödsinn. Egal was faktisch passiert -- es ist am Ausgangsort hinterher nicht mehr da, dass ist also nicht das was man erwarten würde, wenn das Programm nur meldet, dass kopiert wurde.
Habe nun ein "try...except" eingebaut. Ich hoffe das ist so OKEs werden keine Fehler behandelt und der Test vor dem Anlegen eines Verzeichnisses ist überflüssig. Da sollte man einfach versuchen das Verzeichnis anzulegen und eventuelle Fehler dabei ordentlich behandeln. Es können da so nämlich mindestens zwei Dinge passieren: 1. Der Test sagt alles ist okay, und kurz bevor das Verzeichnis angelegt werden soll, macht das ein anderer Prozess, oder 2. es gibt kein Verzeichnis mit dem Namen, aber eine *Datei*. In beiden Fällen haut's Dir eine Ausnahme um die Ohren.
Vielen Dank, dass du dir die Zeit genommen hast, ich lerne hierdurch ne ganze Menge
Ich habe noch eine Änderung des Ordnernamens vollzogen: Aus 2009-08-12 wird 2009_08_12. Das habe ich gemacht, da die Ordner nahtlos zu den anderen Ordnern passen sollen, die ich habe. Des Weiteren ist nun noch eine Variable Englisch.
Der neue Code:
Code: Alles auswählen
import shutil
import os
import datetime
from tkFileDialog import askdirectory
#Quelle waehlen und als "source" speichern
def choosesource():
global source
source = askdirectory()
#Ziel waehlen und als "destination" speichern
def choosedestination():
global destination
destination = askdirectory()
#Startet die Abfragen beim Aufruf
choosesource()
choosedestination()
os.chdir(source)
bilder = []
for dat in os.listdir(os.getcwd()):
if dat.endswith('.jpg') or dat.endswith('.JPG'):
bilder.append(dat)
#ordner erstellen und kopieren
for bild in bilder:
cap = str(datetime.date.fromtimestamp(os.path.getatime(bild)))
capturedate = cap[0:4] + '_' + cap[5:7] + '_' + cap[8:10]
os.chdir(destination)
try:
os.mkdir(capturedate)
except:
pass
os.chdir(source)
shutil.copy(bild, os.path.join(destination, capturedate))
# os.remove(bild)
print bild, 'wurde nach ', capturedate, 'kopiert'
#Jetzt wurde kopiert :P 'os.remove' erstmal als Kommentar behalten, falls ich mir es anders ueberlege
print 'Vorgang abgeschlossen'
so?Jetzt kann das "global" doch bleiben, oder? Ich weiß nämlich sonst nicht, wie ich den Wert der Funktion in eine Variable außerhalb verpackt kriege.
Code: Alles auswählen
def choosesource():
return askdirectory()
source=choosesource()
for file in os.listdir(source): pass
Wenn du die '-' lieber mit '_' ersetzen willst, benutze cap.replace('-', '_')
@ BlackJack
Was ist an os.chdir() so schlimm?
Meiner Meinung nach .... schwachsinn..
Die Funktionen machen beide das gleiche!
ein "return" wäre da sinnvoller.
Und da "asdirectory()" auch nichts anderes mach als den Pfad zurückzuliefern, kann man gleich schreiben
print 'Start wählen'
START=asdirectory()
print 'Ziel wählen'
ZIEL=askdirectory()
@ BlackJack
Was ist an os.chdir() so schlimm?
iScream hat geschrieben:Code: Alles auswählen
from tkFileDialog import askdirectory #Quelle waehlen und als "source" speichern def choosesource(): global source source = askdirectory() #Ziel waehlen und als "destination" speichern def choosedestination(): global destination destination = askdirectory() #Startet die Abfragen beim Aufruf
Meiner Meinung nach .... schwachsinn..
Die Funktionen machen beide das gleiche!
ein "return" wäre da sinnvoller.
Und da "asdirectory()" auch nichts anderes mach als den Pfad zurückzuliefern, kann man gleich schreiben
print 'Start wählen'
START=asdirectory()
print 'Ziel wählen'
ZIEL=askdirectory()
Neu gelerntes sofort umgesetzt Du solltest aber noch einen Blick in PEP8 werfen.Pascal hat geschrieben:Und da "asdirectory()" auch nichts anderes mach als den Pfad zurückzuliefern, kann man gleich schreiben
print 'Start wählen'
START=asdirectory()
print 'Ziel wählen'
ZIEL=askdirectory()
Zum chdir: Damit wechselst du das Arbeitsverzeichnis. Normalerweise sollte man/ein Außenstehender davon ausgehen können, dass das Arbeitsverzeichnis gleich bleibt und sich dort befindet, wo man es angegeben hat/das Script gestartet hat. Außerdem arbeitet man beim Wechsel des Verzeichnis auf globalen Variablen. Rufst du verschachtelte Funktionen auf, die alle was auf Verzeichnissen machen und alle irgendwie wechseln, dann baust du dir mit Sicherheit einen Fehler ein.
@iScream: der Code ist ja noch schlimmer geworden
Das "if __name__ ..." sollte nicht verschwinden sondern ganz ans Ende des Codes. Was verschwinden soll ist der Code auf Modulebene. Das bedeutet bei dir konkret: Teile dein Programm in sinnvolle Funktionen auf.
"global" ist niemals eine Lösung. Verwende es einfach nicht. Wenn du es einsetzt, dann machst du etwas falsch. Die Lösung dieses Problems sind Rückgabewerte und Parameter. Es gilt: eine Funktion sollte keine Seiteneffekte haben, natürlich abgesehen von IO und Konsorten. Maximal sollten sich die Parameter verändern.
Dein try-except fängt ALLE Fehler ab, dass kann manchmal zu seltsamen Fehlern führen, die nicht nachvollziehbar sind. Gebe also immer die Fehler an, die abgefangen werden sollen. Eine Fehlerbehandlung mit einem "pass" ist in den Meisten fällen auch Unfug - so wie bei dir. Es kann nämlich durchaus passieren, dass das Verzeichnis nicht erstellt werden konnte. Dann läuft dein Programm weiter, liefert dann aber sicher in Zeile 35 einen Fehler.
Das Leben ist wie ein Tennisball.
@iScream: Du hast das Falsche verschwinden lassen. Der Code sollte in eine Funktion, die dann in der ``if __name__``-Überprüfung aufgerufen wird.
``global`` sollte man grundsätzlich meiden. Wenn Du nicht weisst wie man mit Funktionen arbeitet, solltest Du wirklich mal das Tutorial in der Python-Dokumentation durcharbeiten.
Wieso weisst Du nicht, wie Du ohne das Arbeitsverzeichnis zu wechseln an die Bilder kommst? Du *tust* das doch sogar schon für das Zielverteichnis, weil man ja immer nur in einem Arbeitsverzeichnis gleichzeitig sein kann.
Für das `capturedate` würde ich nicht die `str()`-Repräsentation von dem `date`-Objekt nehmen, sondern dessen `strftime()`-Methode. Dann kannst Du auch gleich Unterstriche einsetzen, und musst die nicht hinterher ersetzen.
Ein ``except`` ohne eine konkrete Ausnahme in dem dann auch noch einfach gar nichts gemacht wird, ist keine gute Idee. Damit kann man Fehlersituationen "maskieren", nach denen man sich im Ernstfall dumm und dusselig sucht, weil man wichtige Informationen einfach nicht bekommt.
@Pascal: Bei `os.chdir()` muss man *programmweit* immer aufpassen, dass man an jeder Stelle weiss, welches Verzeichnis zur Laufzeit das Aktuelle an dieser Stelle ist. Spätestens wenn man das auch in Bibliotheken macht, oder mehrere Threads benutzt, wird so ein Programm unwartbar. Schon bei bedingten Verzweigungen kann es unübersichtlich werden, weil man für jeden möglichen Auführungspfad sicherstellen muss, das die Verzeichniswechselei richtig läuft und nicht irgendwo mal "übergangen" wird.
``global`` sollte man grundsätzlich meiden. Wenn Du nicht weisst wie man mit Funktionen arbeitet, solltest Du wirklich mal das Tutorial in der Python-Dokumentation durcharbeiten.
Wieso weisst Du nicht, wie Du ohne das Arbeitsverzeichnis zu wechseln an die Bilder kommst? Du *tust* das doch sogar schon für das Zielverteichnis, weil man ja immer nur in einem Arbeitsverzeichnis gleichzeitig sein kann.
Für das `capturedate` würde ich nicht die `str()`-Repräsentation von dem `date`-Objekt nehmen, sondern dessen `strftime()`-Methode. Dann kannst Du auch gleich Unterstriche einsetzen, und musst die nicht hinterher ersetzen.
Ein ``except`` ohne eine konkrete Ausnahme in dem dann auch noch einfach gar nichts gemacht wird, ist keine gute Idee. Damit kann man Fehlersituationen "maskieren", nach denen man sich im Ernstfall dumm und dusselig sucht, weil man wichtige Informationen einfach nicht bekommt.
@Pascal: Bei `os.chdir()` muss man *programmweit* immer aufpassen, dass man an jeder Stelle weiss, welches Verzeichnis zur Laufzeit das Aktuelle an dieser Stelle ist. Spätestens wenn man das auch in Bibliotheken macht, oder mehrere Threads benutzt, wird so ein Programm unwartbar. Schon bei bedingten Verzweigungen kann es unübersichtlich werden, weil man für jeden möglichen Auführungspfad sicherstellen muss, das die Verzeichniswechselei richtig läuft und nicht irgendwo mal "übergangen" wird.
Gut, das seh ich ein.BlackJack hat geschrieben: @Pascal: Bei `os.chdir()` muss man *programmweit* immer aufpassen, dass man an jeder Stelle weiss, welches Verzeichnis zur Laufzeit das Aktuelle an dieser Stelle ist. Spätestens wenn man das auch in Bibliotheken macht, oder mehrere Threads benutzt, wird so ein Programm unwartbar. Schon bei bedingten Verzweigungen kann es unübersichtlich werden, weil man für jeden möglichen Auführungspfad sicherstellen muss, das die Verzeichniswechselei richtig läuft und nicht irgendwo mal "übergangen" wird.
bei shutil.copy müsste man dann allerdings (START+'/pic.jpg' , ZIEL) angeben. Dann geht das auch. (Das war nämlich mein Problem, deswegen der Verzeichnis wechsel)
Und noch eine Frage hinterher:
Wäre shutil.copy2 nicht eigentlich besser geeignet?
Oder shutil.move ?
Bitte erklärt das nochmal genauer, ich verstehe es leider noch nicht ganz.
Das Programm soll also mit "if __name__" aufgerufen werden?
Es sollte nur aus einer Funktion bestehen?!
Das except sollte zunächst auch nur zur Maskierung dienen. Arbeite ich noch dran
Das Programm soll also mit "if __name__" aufgerufen werden?
Es sollte nur aus einer Funktion bestehen?!
Das except sollte zunächst auch nur zur Maskierung dienen. Arbeite ich noch dran
Code: Alles auswählen
#deine Funktionen hier
def main():
#hier dein Code, der auch die Funktionen auruft
if __name__ == "__main__":
main()
@Pascal:
Nein, dann möchtest du "os.path.join" benutzen.Pascal hat geschrieben:bei shutil.copy müsste man dann allerdings (START+'/pic.jpg' , ZIEL) angeben
Das Leben ist wie ein Tennisball.
ich habe mal probiert das os.chdir() zu vermeiden
Das Programm ist jetzt allerdings noch ungetestet (Hatte keine passende Verzeichnisse)
Ich hoffe ich hab nichts übersehen
Das Programm ist jetzt allerdings noch ungetestet (Hatte keine passende Verzeichnisse)
Code: Alles auswählen
import shutil
import os
import datetime
from tkFileDialog import askdirectory
print 'Startverzeichnis wählen:'
start=askdirectory()
print 'Zielverzeichnes wählen:'
ziel=askdirectory()
print 'Alle gefundenen Bilder in %s werden nach %s kopiert' %(start, ziel)
print 'Sollen die Bilder nach dem kopieren aus dem Startverzeichnis gelöscht werden? (Y oder N)'
bilder_loeschen=raw_input()
d={'Y':True, 'N': False}
try:
bilder_loeschen=d[bilder_loeschen]
except KeyError:
print 'Du Idiot! Nur Y oder N eingeben'
#raise SystemExit('Selber Schuld! (Gib beim nächsten Mal Y oder N ein!)')
bilder=[]
for dat in os.listdir(start):
if dat[:-4] in ['.jpg', '.JPG', '.gif', '.png', '.bmp']:
bilder.append(dat)
#ordner erstellen und kopieren
for bild in bilder:
aufnahme=str(datetime.date.fromtimestamp(os.path.getatime(bild)))
if not os.path.isdir(os.path.join(ziel, aufnahme)):
os.mkdir(os.path.join(ziel, aufnahme))
shutil.copy(os.path.join(start, bild), os.path.join(ZIEL, aufnahme))
if bilder_loeschen:
os.remove(os.path.join(start, bild))
print bild, 'wurde nach ', aufnahme, 'verschoben'
else:
print bild, 'wurde nach ', aufnahme, 'kopiert'
print
print 'Vorgang abgeschlossen'
Code: Alles auswählen
import shutil
import os
import datetime
from tkFileDialog import askdirectory
from tkMessageBox import askyesno
def movefiles(from_, to, keepold=False):
print 'Alle gefundenen Bilder in %s werden nach %s kopiert' %(start, ziel)
for file in os.listdir(from_):
if filter( file.lower().endswith, ['.jpg', '.gif', '.png', '.bmp'])
#ist das so sinnvoll?
aufnahme=str(datetime.date.fromtimestamp(os.path.getatime(file)))
try:
os.mkdir(os.path.join(to, aufnahme))
except OSError, error:
if error.errno !=17:
raise
if keepold:
shutil.copy(os.path.join(from_, file), os.path.join(to, aufnahme))
print bild, 'wurde nach ', aufnahme, 'kopiert'
else:
shutil.move(os.path.join(from_, file), os.path.join(to, aufnahme))
print bild, 'wurde nach ', aufnahme, 'verschoben'
def main():
#wieso nochmal schreiben wenn per gui gefragt wird?
print 'Startverzeichnis wählen:'
start=askdirectory()
print 'Zielverzeichnes wählen:'
ziel=askdirectory()
movefiles(start, ziel, askyesno('Achtung', 'remove old?'))
print 'Vorgang abgeschlossen'
if __name__ == '__main__':
main()
- zum Beispiel nur eine Sprache verwenden
- file nicht zu überschreiben
- und
als
Sonst sind es ja nur noch sehr kleine Kleinigkeiten.
- file nicht zu überschreiben
- und
Code: Alles auswählen
if keepold:
shutil.copy(os.path.join(from_, file), os.path.join(to, aufnahme))
else:
shutil.move(os.path.join(from_, file), os.path.join(to, aufnahme))
Code: Alles auswählen
action = shutil.copy if keepod else shutil.move
action(os.path.join(from_, file), os.path.join(to, aufnahme))
Das Leben ist wie ein Tennisball.
Ich habe auch mal etwas (ungetestetes) gehackt:
@jbs: So umgeht man die "magische" 17 für den Fall, dass der Pfad schon existiert.
Code: Alles auswählen
#!/usr/bin/env python
from __future__ import division, with_statement
import errno
import os
import shutil
from datetime import date as Date
from tkFileDialog import askdirectory
def is_jpg(filename):
return filename.lower().endswith('.jpg')
def iter_jpg_names(path):
return (os.path.join(path, f) for f in os.listdir(path) if is_jpg(f))
def copy_file(source_path, target_path):
date = Date.fromtimestamp(os.path.getatime(source_path))
full_target_path = os.path.join(target_path, date.strftime('%Y_%m_%d'))
try:
os.mkdir(full_target_path)
except OSError, error:
if error.errno != errno.EEXIST:
raise
shutil.copy(source_path, full_target_path)
def main():
source_path = askdirectory()
target_path = askdirectory()
for jpg_filename in iter_jpg_names(source_path):
copy_file(jpg_filename, target_path)
print '%r wurde nach %r kopiert' % (jpg_filename, full_target_path)
print 'Vorgang abgeschlossen.'
if __name__ == '__main__':
main()
Hey
Es gibt sicher noch Verbesserungmöglichkeiten am Code, doch er übertrifft jetzt schon meine Erwartungen an Komfort und Funktionalität bei weitem
Ich möchte euch allen danken, dass ihr euch soviel Zeit genommen habt. Ich habe viel Neues gelernt und einen gut funktionierendes Skript, was mich von einer weiteren Windows-Software erlöst und mich somit Linux näher bringt
lg,
iScream
Es gibt sicher noch Verbesserungmöglichkeiten am Code, doch er übertrifft jetzt schon meine Erwartungen an Komfort und Funktionalität bei weitem
Ich möchte euch allen danken, dass ihr euch soviel Zeit genommen habt. Ich habe viel Neues gelernt und einen gut funktionierendes Skript, was mich von einer weiteren Windows-Software erlöst und mich somit Linux näher bringt
lg,
iScream
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
iScream: Hast du schon von digikam gehört? Ist eine komplette Fotoverwaltung mit Bewertung, Tagging, mächtigen Plugins etc. und läuft unter GNU/Linux. Ein echter Grund zum Wechseln.