Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 21, 2010 11:30:21

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

Вот скрипт

# -*- 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



Офлайн

#2 Апрель 21, 2010 11:40:03

Puppy
От:
Зарегистрирован: 2010-02-23
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

попробуй val = val.encode('cp1251')



Офлайн

#3 Апрель 21, 2010 11:47:22

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

Пробовал, тоже самое.
3-й скрипт который я привел работает, не могу понять почему не работает 4-й



Офлайн

#4 Апрель 21, 2010 11:54:02

Puppy
От:
Зарегистрирован: 2010-02-23
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

Я в таких случаях что только не делаю и decode и encode, и двойные кавычки ‘“’+val+'”'



Офлайн

#5 Апрель 21, 2010 11:59:47

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

И что-нибудь работает?



Офлайн

#6 Апрель 21, 2010 12:06:19

Puppy
От:
Зарегистрирован: 2010-02-23
Сообщения: 26
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

svas
И что-нибудь работает?
обязательно ))
наверное кавычки помогут. хм



Отредактировано (Апрель 21, 2010 12:07:34)

Офлайн

#7 Апрель 21, 2010 13:24:19

Nik
От:
Зарегистрирован: 2010-01-10
Сообщения: 77
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

>>> 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)
Так что в вашем случае даже до записи в файл дело не доходит…



Отредактировано (Апрель 21, 2010 13:35:21)

Офлайн

#8 Апрель 21, 2010 17:08:51

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

нужно значение “getattr(p, pname)” преобразовать в уникод

Офлайн

#9 Апрель 21, 2010 19:43:43

svas
От:
Зарегистрирован: 2010-01-27
Сообщения: 239
Репутация: +  9  -
Профиль   Отправить e-mail  

Проблема с кодировкой и записью в файл

Ну примерно разобрался, спасибо



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version