Найти - Пользователи
Полная версия: Проблема с кодировкой и записью в файл
Начало » Python для новичков » Проблема с кодировкой и записью в файл
1
svas
Вот скрипт
# -*- coding: UTF-8 -*-

import wmi

c = wmi.WMI()

f = open('filename.txt', 'wt')
for p in c.Win32_MotherboardDevice():
for pname in sorted(p.properties.keys()):
f.write('%s: %s\n' % (pname, getattr(p, pname)))
f.write('-'*20+'\n')
Вылетает ошибка, как только встречаются русские символы
Traceback (most recent call last):
File "C:\tmp\wmitest.py", line 10, in <module>
f.write('%s: %s\n' % (pname, getattr(p, pname)))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 9-19: ordinal not in range(128)
Если выводить не в файл а в консоль то все нормально:
# -*- coding: UTF-8 -*-

import wmi

c = wmi.WMI()

for p in c.Win32_MotherboardDevice():
for pname in sorted(p.properties.keys()):
print '%s: %s' % (pname, getattr(p, pname))
print '-'*20
Вывод:
Availability: None
Caption: Материнская плата
ConfigManagerErrorCode: None
ConfigManagerUserConfig: None
CreationClassName: Win32_MotherBoardDevice
Description: Материнская плата
DeviceID: Motherboard
ErrorCleared: None
ErrorDescription: None
InstallDate: None
LastErrorCode: None
Name: Материнская плата
PNPDeviceID: None
PowerManagementCapabilities: None
PowerManagementSupported: None
PrimaryBusType: PCI
RevisionNumber: None
SecondaryBusType: ISA
Status: None
StatusInfo: None
SystemCreationClassName: Win32_ComputerSystem
SystemName: WIN1
Не могу понять в чем проблема. Например вот такой скрипт тоже работает:
# -*- coding: UTF-8 -*-

import wmi

c = wmi.WMI()

f = open('filename.txt', 'wt')
for p in c.Win32_MotherboardDevice():
f.write('%s\n' % getattr(p, 'Caption').encode('utf-8'))
А вот такой нет, вылетает такое же исключение при попытке записи свойства ‘Caption’:
# -*- coding: UTF-8 -*-

import wmi

c = wmi.WMI()

f = open('filename.txt', 'wt')
for p in c.Win32_MotherboardDevice():
for pname in sorted(p.properties.keys()):
val = getattr(p, pname)
if type(val) == unicode:
val = val.encode('utf-8')
else:
val = str(val)
f.write('%s: %s\n' % (pname, val))
f.write('\n\n')
Вылетает такое исключение:
Traceback (most recent call last):
File "C:\tmp\wmitest3.py", line 16, in <module>
f.write('%s: %s\n' % (pname, val))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
Как правильно сделать?
Python 2.5.4, OS - Windows XP SP3
Puppy
попробуй val = val.encode('cp1251')
svas
Пробовал, тоже самое.
3-й скрипт который я привел работает, не могу понять почему не работает 4-й
Puppy
Я в таких случаях что только не делаю и decode и encode, и двойные кавычки ‘“’+val+'”'
svas
И что-нибудь работает?
Puppy
svas
И что-нибудь работает?
обязательно ))
наверное кавычки помогут. хм
Nik
>>> s1 = unicode("string1", "cp1251")
>>> s2 = "string2"
>>> type(s1), type(s2)
(<type 'unicode'>, <type 'str'>)
>>> type("%s" % s1)
<type 'unicode'>
>>> type("%s" % s2)
<type 'str'>
>>> s3 = "%s%s" % (s1, s2)
>>> type(s3)
<type 'unicode'>
>>> type(s3.encode("cp1251"))
<type 'str'>
Итог: если в операции форматирования участвуют unicode строка и обычная строка, то в результате получится unicode строка. Поэтому ваши строки
svas
if type(val) == unicode:
val = val.encode('utf-8')
else:
val = str(val)
f.write('%s: %s\n' % (pname, val))
бессмысленны… pname по прежнему unicode строка. В файл вы по прежнему пытаетесь записать unicode строку. При записи в файл в Windows кодировка терминала (атрибут encoding) не определена. Поэтому используется кодировка, указанная в модуле site. А там такая строка:
encoding = "ascii" # Default value set by _PyUnicode_Init()
Русские символы в ascii не входят. Отсюда ошибка. Что касается вывода в консоль, то там кодировка терминала определена. Поэтому вывод будет корректным:

>>> f = open("test.txt", "w")
>>> f.encoding
>>> import sys
>>> sys.stdout.encoding
'cp1251'
Кстати, при попытке форматирования смешанных строк обычная строка преобразуется в unicode строку. Уже на этом этапе вы получите ошибку:
>>> '%s: %s\n' % (unicode("str", "cp1251"), "Обычная строка")
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
'%s: %s\n' % (unicode("str", "cp1251"), "Обычная строка")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
Так что в вашем случае даже до записи в файл дело не доходит…
o7412369815963
нужно значение “getattr(p, pname)” преобразовать в уникод
svas
Ну примерно разобрался, спасибо
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB