ASCII Code Fehler

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
BlueDogi
User
Beiträge: 30
Registriert: Mittwoch 29. April 2015, 22:25

Hallo zusammen

ich habe volgende Funktion:

Code: Alles auswählen

def CreateXlsxFile(DestinationDirectory, NameXlsxFile, DirectoryList, Logger):
    Logger.info('start function "CreateXlsxFile"')
    try:
        XlsxFilePath = os.path.join(DestinationDirectory, NameXlsxFile)
        workbook = xlsxwriter.Workbook(XlsxFilePath)
        worksheet = workbook.add_worksheet('FindeInDocu')
        for zeile, Directory in enumerate(DirectoryList, 1):
            for spalte, path in enumerate(PathToList(Directory, Logger)[2:]):
                Logger.debug('Directory= ' + Directory)
                worksheet.write_url(row=zeile, col=spalte, url=ur'external:%s' %Directory.decode('utf-8') , string=path)
        workbook.close()
        Logger.info('function "CreateXlsxFile" finished without Error')
    except Exception, e:
        Logger.error('function "CreateXlsxFile" finished with Error')
        Logger.debug(e, exc_info=True)
Ich bekomme diesen Fehler:

Code: Alles auswählen

'utf8' codec can't decode byte 0xf6 in position 35: invalid start byte
Traceback (most recent call last):
  File "Doku_nach_Excel.py", line 120, in CreateXlsxFile
    worksheet.write_url(row=zeile, col=spalte, url=ur'external:%s' %Directory.decode('utf-8') , string=path)
  File "C:\python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf6 in position 35: invalid start byte
Der Byte Code 0xf6 heißt in ASCII so viel wie ö. Directory beinhaltet z.B. den String „D:\Test\töst“.
Um erlich zu sein habe ich von den verschiedenen Zeichen Codes nicht viel Ahnung. Ich habe bereits
ur’string‘
ausprobiert leider ohne Erfolg. Auserdem habe ich schon
unicode(Directory, "ISO-8859-1")
ausprobiert leider ebenfalle ohne Erfolgs

Das komplette Programm habe ich grade leider nicht zur Verfügung. Werde es aber schnellst möglich nachliefern.

Vielen Dank!
BlackJack

@BlueDogi: ASCII kennt kein 'ö', Du musst also schon wissen welche Kodierung Deine Daten verwenden und entsprechend dekodieren. ISO-8859-1 könnte für '\xf6' als 'ö' hinkommen, also ist die Frage was dabei „ohne Erfolg“ bedeutet.
BlueDogi
User
Beiträge: 30
Registriert: Mittwoch 29. April 2015, 22:25

Der String ist als utf8 codiert. Wenn ich ur’string‘ benutze sieht der Fehler so aus.

Code: Alles auswählen

'ascii' codec can't decode byte 0xf6 in position 35: ordinal not in range(128)
Traceback (most recent call last):
  File "Doku_nach_Excel.py", line 120, in CreateXlsxFile
    worksheet.write_url(row=zeile, col=spalte, url=ur'external:%s' %Directory, string=path)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 35: ordinal not in range(128)
Wenn ich r’string‘ benutze kommt der Fehler:

Code: Alles auswählen

'ascii' codec can't decode byte 0xf6 in position 26: ordinal not in range(128)
Traceback (most recent call last):
  File "Doku_nach_Excel.py", line 121, in CreateXlsxFile
    workbook.close()
  File "C:\python27\lib\xlsxwriter\workbook.py", line 295, in close
    self._store_workbook()
  File "C:\python27\lib\xlsxwriter\workbook.py", line 518, in _store_workbook
    xml_files = packager._create_package()
  File "C:\python27\lib\xlsxwriter\packager.py", line 140, in _create_package
    self._write_shared_strings_file()
  File "C:\python27\lib\xlsxwriter\packager.py", line 280, in _write_shared_strings_file
    sst._assemble_xml_file()
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 53, in _assemble_xml_file
    self._write_sst_strings()
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 83, in _write_sst_strings
    self._write_si(string)
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 110, in _write_si
    self._xml_si_element(string, attributes)
  File "C:\python27\lib\xlsxwriter\xmlwriter.py", line 122, in _xml_si_element
    self.fh.write("""<si><t%s>%s</t></si>""" % (attr, string))
  File "C:\python27\lib\codecs.py", line 694, in write
    return self.writer.write(data)
  File "C:\python27\lib\codecs.py", line 357, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 26: ordinal not in range(128)
Ich habe nun die Vermutung das worksheet.write_url() ein Problem mit dem UTF8 sting hat. Aber meine Weisheit in Sachen Zeichen Codierung ist sehr beschränkt.

Wie Versprochen mein Kompletter Code:
http://codeviewer.org/view/code:538d
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

BlueDogi hat geschrieben:Der String ist als utf8 codiert.
Nein, das ist er nicht. Wäre es UTF-8 dann würdest du nicht die Meldung "UnicodeDecodeError: 'utf8' codec can't decode byte 0xf6 in position 35: invalid start byte" erhalten.

Hast du eigentlich überhaupt versucht die von Blackjack vorgeschlagene Codierung ISO-8859-1 zu verwenden? Du musst dafür doch nur Directory.decode('utf-8') durch Directory.decode('iso-8859-1') ersetzen. Das sollte zumindest dieses erste Problem lösen.
BlackJack

@BlueDogi: So ganz allgemein finde ich den Quelltext schwer zu lesen weil sich die Namensschreibweise nicht an den Style Guide for Python Code.

Sternchen-Importe sind böse. Bei dem bei `os` kann man im Modul zum Beispiel eine Überraschung erleben wenn man versucht eine Datei mit der eingebauten `open()`-Funktion zu öffnen. Die gibt's nämlich nicht mehr weil sie von `os.open()` verdeckt wird. Zudem scheint mir aus dem Modul überhaupt gar nichts gebraucht zu werden was nicht sowieso über das ebenfalls importierte Modul angesprochen wird.

``return`` ist keine Funktion, dementsprechend gehört der Wert dahinter auch nicht in Klammern, denn das ist kein Argument.

`CrateLogger()`, `ConfigParse`, und `ImortStructure()` sind falsch geschrieben. Was ist der Unterschied zwischen `LogFile` und `LogDatei` in *einer* Funktion? Bitte ohne nachzusehen beantworten und mit Begründung warum die so benannt sind. Tipp: Es gibt Dateien als Werte und es gibt Dateinamen als Werte. Die sollte man eindeutig am Namen unterscheiden können.

Logger sind eine der wenigen Ausnahmen wo sich eine modulglobale Variable anbietet, oder man holt sich den immer mit der `getLogger()`-Funktion wo man ihn braucht. Dann könnte man vieles von der Logging-Funktionalität abkürzen in dem man einen Dekorator schreibt. Andererseits ist diese Art der Ausnahmebehandlung die Du da machst ziemlicher Unsinn und führt teilweise zwangsläufig zu Folgefehlern, also doch wieder zu einer Ausnahme.

`Logger` kennen eine `exception()`-Methode.
BlueDogi
User
Beiträge: 30
Registriert: Mittwoch 29. April 2015, 22:25

Ich habe meinen Code noch mal überarbeitet. Ich hoffe er ist jetzt lesbarer.
http://codeviewer.org/view/code:538f
Es kommt zu diesem Fehler:

Code: Alles auswählen

'ascii' codec can't decode byte 0xf6 in position 26: ordinal not in range(128)
Traceback (most recent call last):
  File "Doku_nach_Excel.py", line 129, in CreateXlsxFile
    workbook.close()
  File "C:\python27\lib\xlsxwriter\workbook.py", line 295, in close
    self._store_workbook()
  File "C:\python27\lib\xlsxwriter\workbook.py", line 518, in _store_workbook
    xml_files = packager._create_package()
  File "C:\python27\lib\xlsxwriter\packager.py", line 140, in _create_package
    self._write_shared_strings_file()
  File "C:\python27\lib\xlsxwriter\packager.py", line 280, in _write_shared_strings_file
    sst._assemble_xml_file()
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 53, in _assemble_xml_file
    self._write_sst_strings()
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 83, in _write_sst_strings
    self._write_si(string)
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 110, in _write_si
    self._xml_si_element(string, attributes)
  File "C:\python27\lib\xlsxwriter\xmlwriter.py", line 122, in _xml_si_element
    self.fh.write("""<si><t%s>%s</t></si>""" % (attr, string))
  File "C:\python27\lib\codecs.py", line 694, in write
    return self.writer.write(data)
  File "C:\python27\lib\codecs.py", line 357, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 26: ordinal not in range(128)
Wenn ich die diese Funktion einsetze:

Code: Alles auswählen

def CreateXlsxFile(IniFile, DirectoryList):
    GlobalLogger.info('start function "CreateXlsxFile"')
	
    DestinationDirectory = ReadIniValue(IniFile, "Verzeichnisse",
                                        "Ausgabe_Verzeichnis")

    NameXlsxFile = ReadIniValue(IniFile, "Verzeichnisse",
                                "Name_Excel_Datei")
    try:
        XlsxFilePath = os.path.join(DestinationDirectory, NameXlsxFile)
        workbook = xlsxwriter.Workbook(XlsxFilePath)
        worksheet = workbook.add_worksheet('FindeInDocu')
        for zeile, Directory in enumerate(DirectoryList, 1):
            for spalte, path in enumerate(PathToList(Directory)[2:]):
                GlobalLogger.debug('Directory= ' + Directory)
                url = r'external:%s' %Directory
                url.decode('iso-8859-1')
                print (type(url))
                worksheet.write_url(row=zeile, col=spalte, url=url , string=path)
        workbook.close()
        GlobalLogger.info('function "CreateXlsxFile" finished without Error')
    except Exception, e:
        GlobalLogger.error('function "CreateXlsxFile" finished with Error')
        GlobalLogger.exception(e, exc_info=True)
Kommt es zu diesem Fehler:

Code: Alles auswählen

'ascii' codec can't decode byte 0xf6 in position 26: ordinal not in range(128)
Traceback (most recent call last):
  File "Doku_nach_Excel.py", line 129, in CreateXlsxFile
    workbook.close()
  File "C:\python27\lib\xlsxwriter\workbook.py", line 295, in close
    self._store_workbook()
  File "C:\python27\lib\xlsxwriter\workbook.py", line 518, in _store_workbook
    xml_files = packager._create_package()
  File "C:\python27\lib\xlsxwriter\packager.py", line 140, in _create_package
    self._write_shared_strings_file()
  File "C:\python27\lib\xlsxwriter\packager.py", line 280, in _write_shared_strings_file
    sst._assemble_xml_file()
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 53, in _assemble_xml_file
    self._write_sst_strings()
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 83, in _write_sst_strings
    self._write_si(string)
  File "C:\python27\lib\xlsxwriter\sharedstrings.py", line 110, in _write_si
    self._xml_si_element(string, attributes)
  File "C:\python27\lib\xlsxwriter\xmlwriter.py", line 122, in _xml_si_element
    self.fh.write("""<si><t%s>%s</t></si>""" % (attr, string))
  File "C:\python27\lib\codecs.py", line 694, in write
    return self.writer.write(data)
  File "C:\python27\lib\codecs.py", line 357, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf6 in position 26: ordinal not in range(128)
Meine Vermutung ist nun das XlsxWrter nur ascii umgehen kann. Oder nach ascii konvertieren will dies geht aber nicht...

Ich habe keinen Schimmer. :K
BlackJack

@BlueDogi: `url` hast Du dekodiert, aber `path` enthält doch das *gleiche* Byte das ausserhalb von ASCII liegt und auch `path` wird ins Exceldokument geschrieben‽

Edit: Gnarf, ich sehe gerade nach Sirius3 dezentem Hinweis das Du `url` zwar dekodierst, aber das Ergebnis dann gleich wieder verwirfst…
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlueDogi: nein, XLSX-Writer erwartet Unicode. Deshalb kommt es ja auch zu einem Decodierfehler.
Was glaubst Du bewirkt bei dem gezeigten Code-Abschnitt Zeile 17?
BlueDogi
User
Beiträge: 30
Registriert: Mittwoch 29. April 2015, 22:25

Jetzt geht’s! Danke!
Lösung:

Code: Alles auswählen

def CreateXlsxFile(IniFile, DirectoryList):
    GlobalLogger.info('start function "CreateXlsxFile"')
	
    DestinationDirectory = ReadIniValue(IniFile, "Verzeichnisse",
                                        "Ausgabe_Verzeichnis")

    NameXlsxFile = ReadIniValue(IniFile, "Verzeichnisse",
                                "Name_Excel_Datei")
    try:
        XlsxFilePath = os.path.join(DestinationDirectory, NameXlsxFile)
        workbook = xlsxwriter.Workbook(XlsxFilePath)
        worksheet = workbook.add_worksheet('FindeInDocu')
        for row, Directory in enumerate(DirectoryList, 1):
            for colume, path in enumerate(PathToList(Directory)[1:]):
                GlobalLogger.debug('Directory= ' + Directory)
                url = r'external:%s' %Directory
                url = url.decode('iso-8859-1')
                path = path.decode('iso-8859-1')
                print (type(url))
                worksheet.write_url(row=row, col=colume, url=url , string=path)
        workbook.close()
        GlobalLogger.info('function "CreateXlsxFile" finished without Error')
    except Exception, e:
        GlobalLogger.error('function "CreateXlsxFile" finished with Error')
        GlobalLogger.exception(e, exc_info=True)
Wenn euch noch was an meinem Code stört sagt es bitte. Das kann mir ja nur weiter helfen.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@BlueDogi: ein Logger ist wohl per Konvention global, das muß man nicht unbedingt in den Namen schreiben, wobei die Namensgebung sich immer noch nicht an die üblichen Konventionen hält und damit der Code schwierig zu lesen ist. Etliche male die selbe URL zu ermitteln ist blöd. Dass das Directory mehrmals an unterschiedlichen Stellen dekodiert wird auch. Warum ist die Info "... finished with Error" ein Error? Dass ein Fehler passiert ist sieht man doch am Traceback. Ist IniFile eine Ini-Datei oder sind das vielleicht doch Konfigurationsparameter? Warum werden die in der Funktion ermittelt und nicht per Parameter übergeben?
Antworten