Seltsamer Encoding Error

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
relentless92
User
Beiträge: 1
Registriert: Freitag 20. Januar 2012, 00:16

Hallo liebes Board,

Ich habe mich hier mal registriert und sage hiermit offiziell Hallo =)
Natürlich hab ich auch ein kleines Problemchen im Rucksack, weshalb ich hoffe, das ihr mir helfen könnt.

Ich bekomme bei der Ausführung meines Programmes immer einen seltsamen Error. Es startet gar nicht erst, sondern bricht gleich mit "SyntaxError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)"

Ich weis damit leider nichts anzufangen, da ich a) nichts bewusst codieren möchte und b) ich über google nur absichtliche Codierungen, aber keine Problembeschreibungen gefunden hab. Hier mal das Stück Code (der Error springt auf Line 26 an)

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: ascii -*-
		  
import os
import shutil

print '////////'
print '|mskord|'
print '////////'

outdir = raw_input('Output Directory: (e.g. output/): ')

try:
	os.mkdir(outdir)
except:
	print 'Directory exists.'
	
filedir = raw_input('Directory where the Files are: (e.g. files/): ')

dir = os.listdir(filedir);													''' Verzeichnisliste get '''

for filename in dir:														''' Für jede File as Filename innerhalb von dir '''

	print'-----'															''' Konsolenbreak '''
	print filename+'\n'
	
	inde=0																	''' Counter im String '''
	for char in filename:													''' Für Char in Filename '''
		inde=inde+1
		if char == '-': break												''' Select Unterbrechungszeichen '''
		
	newstr = filename[:inde-2]												''' newstr = Interpret '''
	if len(newstr)<1: newstr='_error'
	
	if newstr.lower() != erstellt.lower():									''' Gibts den Interpreten schon? '''
		try: 																''' try except wegen os.error '''
			os.mkdir(outdir+newstr)
		except:
			print 'Directory exists'
			
		erstellt = newstr													''' Existierenen Interpreten setten '''
	
	
	print 'Building: '+newstr												''' Output geben '''
	print 'Copying '+filename+' to '+newstr
	
	shutil.copy2(filedir+filename,outdir+newstr)							''' File umkopieren '''
	
print '/////////////////////////////////////////'
print 'Job done.'
Zuletzt geändert von Anonymous am Freitag 20. Januar 2012, 04:54, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

Wieso nutzt du ascii als Kodierung? Von wegen du versuchst nichts extra zu enkodieren, du Lustikus. "0xe4" ergibt so umkodiert "ä" und die Fehlermeldung sieht so aus als würde ein Dateiname damit anfangen und daher den Fehler verursachen.
BlackJack

@relentless92: Du sagst in der zweiten Zeile dass der Quelltext als ASCII kodiert ist, hast aber im Quelltext dann Zeichen, die sich nicht als ASCII kodieren lassen. In dem Kommentar muss die *tatsächlich verwendete* Kodierung stehen.

Sonstige Anmerkungen: Zeilen sollten in der Länge 80 Zeichen nicht überschreiten und Zeichenketten sind keine Kommentare. Diese Art zu kommentieren macht das Programm fast unlesbar wenn Zeilen umgebrochen werden. Viele der Kommentare sind auch total überflüssig, weil da im Kommentar noch einmal 1:1 das steht, was man im Quelltext schon lesen kann. Kommentare sollten *zusätzliche* Informationen liefern und nicht das Offensichtliche noch einmal sagen.

„Nackte” ``except``\s ohne eine konkrete Ausnahme behandeln *jede* Ausnahme, auch solche, mit denen man gar nicht gerechnet hat, und die man so falsch behandelt und damit nicht zu Gesicht bekommt. Das kann zu sehr frustrierenden Fehlersuchen führen.

Semikolons trennen mehrere Anweisungen auf einer Zeile. Wenn man also nur eine Anweisung hat, dann braucht man das auch nicht ans Ende zu schreiben. Mehrere Anweisungen auf einer Zeile sollte man aus Gründen der Lesbarkeit auch vermeiden. Ebenso Ausdrücke direkt nach dem ``:`` bei einzeiligen Blöcken.

Die Einrücktiefe ist per Konvention vier Leerzeichen pro Ebene.

Abkürzungen bei Namen sollte man vermeiden solange sie nicht allgemein bekannt sind. Bei `inde` finde ich es besonders unsinnig dass man sich wegen *einem* Buchstaben, das Verständnis des Quelltextes schwerer macht als nötig.

Das manuelle Hochzählen des Index ist „unpythonisch”. Wenn man in einer ``for``-Schleife den Index zusätzlich zu den Elemeneten benötigt, nimmt man üblicherweise die `enumerate()`-Funktion.

Diese Schleife ist aber sowieso unnötig, denn es gibt zum einen einen Methoden auf Zeichenketten, mit denen man die Position einer Teilzeichenkette suchen kann, und zum anderen sogar welche um eine Zeichenkette an Zeichen aufzuteilen. Das muss man nicht so mühsam selber schreiben.

Dein Algorithmus ist nicht robust gegen Dateinamen, die *kein* Minuszeichen enthalten.

``if len(newstr) < 1:`` ist ein IMHO zu indirekter Weg ``if len(newstr) == 0:`` auszudrücken. Denn es gibt ja nur genau diesen einen Wert der die Bedingung ``< 1`` erfüllen kann. In Python haben leere Zeichenketten, wie alle eingebauten Sequenztypen, zudem im Kontext eines Wahrheitswertes den Wert `False`. Ein ``if not newstr:`` hätte es also auch getan.

Bei der ersten Verwendung von `erstellt` gibt es diesen Namen noch nicht. Das führt also unweigerlich zu einem `NameError`.

Beim Vergleichen werden Gross- und Kleinschreibung durch das `lower()` ignoriert, beim Anlegen eines Verzeichnissen und Kopieren der Dateien dann aber nicht. Das funktioniert so nur unter Windows, und dort auch nur solange das Zieldateisystem Gross- und Kleinschreibung ignoriert.

Der Algorithmus scheint sich darauf zu verlassen, dass `os.listdir()` die Dateinamen sortiert liefert — das wird in der Dokumentation aber ausdrücklich nicht garantiert. Das kann so sein, muss es aber nicht.

Pfadnamen sollte man nicht mit ``+`` sondern mit `os.path.join()` zusammen setzen. Dann muss der Benutzer zum Beispiel den Pfad nicht mit einem Pfadtrenner abschliessen damit das Programm funktioniert.

``+`` um Zeichenketten zusammen zu setzen werden in Python sowieso nicht so oft verwendet. Zum einen gibt es Zeichenkettenformatierung mittels ``%``-Operator oder `format()`-Methode, und zum anderen ist es bei ``print`` nicht nötig wenn man dort mehrere Ausdrücke mit Kommas getrennt angeben kann. Also statt ``print 'Copying '+filename+' to '+newstr`` geht auch ``print 'Copying', filename, 'to', newstr``.

Edit: Die Ausnahmebehandlung ist auch bei der erwarteten Ausnahme falsch, denn einen `OSError` bekommt man nicht nur wenn ein Pfad bereits existiert, sondern auch wenn ein Teilpfad bei `mkdir()` *nicht* existiert, oder wenn der Benutzer nicht die nötigen Rechte besitzt dort ein neues Verzeichnis anzulegen. In den Fällen läuft das Programm einfach weiter und damit in die nächsten Fehler.
Antworten