Найти - Пользователи
Полная версия: Кодировка, запись в файл русских букв
Начало » Python для новичков » Кодировка, запись в файл русских букв
1
funnyman
Я перебрал много способов, просто кучу.. И уже не знаю где искать, может свежий взгляд поможет, вот код:
программа просто генерирует файлик с нужным кол-во столбцов и строк, данные ячеек соотвествуют типу столбцов..
код выложил чисты, без всех извращений которые пробовал
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import codecs
class Generator:
    def __init__(self, col, row, length, enc):
        self.col = col
        self.row = row
        self.length = length
        self.enc = enc
        self.csvTypeOfData = ["Date", "String", "Integer", "Float"]
        self.allChar = u'йцукенгшщзъфывапролджэячсмитьбю'
    def genStr(self):
        length = random.randint(1, self.length)
        rStr = ''
        while length > 0:
            rStr += random.choice(self.allChar)
            length -= 1
        return rStr
    def genDate(self):
        day = random.randint(1, 31)
        month = random.randint(1, 12)
        year = random.randint(60, 99)
        date = str(day) + '/' + str(month) + '/' + str(year)
        return date
    def genInteger(self):
        return random.randint(1, 1000000)
    def genFloat(self):
        return random.randint(1, 1000) * random.random()
    def genHeadCsv(self):
        headOfCsv = []
        count = 0
        while count < self.col:
            nameCol = self.genStr()
            typeCol = random.choice(self.csvTypeOfData)
            self.colsType.append(typeCol)
            colNameType = nameCol + ' ' + typeCol
            headOfCsv.append(colNameType)
            count += 1
        headOfCsv = '; '.join(headOfCsv)
        return headOfCsv
    def Start(self, outfile):
        self.colsType = []
        headCsv = self.genHeadCsv()
        outfile=codecs.open('outfile.txt','a','utf8','ignore')
        #outfile = open(outfile, 'a')
        #outfile.write(headCsv)
        count = 0
        rowData = []
        while self.row > count:
            for csvType in self.colsType:
                if (csvType == 'Date'):
                    cell = self.genDate()
                    rowData.append(cell)
                elif (csvType == 'Integer'):
                    cell = self.genInteger()
                    rowData.append(cell)
                elif (csvType == 'Float'):
                    cell = self.genFloat()
                    rowData.append(cell)
                elif (csvType == 'String'):
                    cell = self.genStr()
                    rowData.append(cell)
            rowData = '; '.join(str(cell) for cell in rowData)
            #rowData = unicode(rowData, 'cp866')
            #rowData = rowData.encode('utf8')
            outfile.write(rowData+'\n')
            rowData = []
            count += 1
        outfile.close()
sakal
Так вопрос то в чём заключается?
warik
Пайтон версии <3 в качестве кодировки по умолчанию использует кодировку АНСИ, поэтому все танцы с юникодом не имеют смысла до того как Вы не измените её.

В самом начале файла делаете это
reload(sys)
sys.setdefaultencoding('utf8')

После этого можете смело использовть юникодовские строки
funnyman
+100500 тебе мэн!
cutwater
+100500 за плохие советы? вот жаль на форуме нет оценки полезности комментария.
Потому что использование setdefaultencoding О-О-ОЧЕНЬ плохая практика.
funnyman
+100500 за срочную помощь и положительный результат Хоть решение и помогло, я не прочь посмотреть на Ваш вариант.
cutwater
Вы бы для начала проблему описали. Вопрос бы задали. А не предложить написать свой вариант. Совет пользователя warik идиотский. Посему можем начать с начала с вопроса “В чем у вас конкретно проблема”.
Вообще наиболее правильное решение - разобраться и почитать документацию как правильно работать с юникодом, а не использовать грязные хаки по типу setdefaultencoding

Советую начинать с этой презентации и видео:

http://www.rupy.ru/static/files/07/02/12/rupyru2007-yurevich-unicode-thesis.pdf
http://video.google.com/videoplay?docid=5035388502434680056
warik
Хорошо, скажу сразу, что прежде чем прийти к предоставленному решению я прочитал несколько статей по юникоду, включая питоновские доки. Я пробовал все то, что описано в указанной Вами презентации и мне ничего не помогло.

Если уж это такое плохое решение, то почему многие им пользуются? (лично я эти решения со stackoverflow брал)

Почему не обрабатываются украинские символы?
s = unicode('їівпапвв', 'utf8')
print s
UnicodeDecodeError

print u'їівпапвв'.encode('utf8')
Так работает, но выдает билеберду. Потому что я раскодирую опять в аски? А почему тогда нельзя просто вывести на печать?

Я не ту кодировку использую?

Почему в первой печати все нормально, а во второй опять ерунда? Потому что во-второй раз это аски?
s = unicode('фывфвывв', 'utf8')
print s
print s.encode('utf8')

Давайте без агрессии, пожалуйста, не нужно кричать. Мы здесь новички и лучше вместо тыкания носом в одни и те же статьи, объясните на пальцах.
cutwater
warik, на всякий случай еще можно было бы указать ОС в которой работаете.
И таки да в Windows с кодировками беда беда. ССЗБ.

warik
Так работает, но выдает билеберду. Потому что я раскодирую опять в аски? А почему тогда нельзя просто вывести на печать?

Потому что в Windows по-умолчанию кодировка в консоли ни разу не UTF-8. Чтобы нормально вывести в консоль нужно делать decode в нужной кодировке. Кодировка у cmd по-умолчанию если мне память не изменяет cp866. Так как у меня сейчас Windows недоступна, я смогу проверить этот вопрос только вечером, дабы не быть голословным. Дальше читать здесь http://wiki.python.org/moin/PrintFails

Хорошая практика: unicode - для внутреннего использования, для передачи наружу (в том числе и print) использовать явное кодирование в нужную кодировку.

Собственно проблема в том что setdefaultencoding не совсем то, что Вы ожидаете. Получая в качестве побочного эффекта результат, который Вас удовлетворяет, Вы вместе с этим получаете проблемы с переносимостью
warik
На работе окна ХР, сегодня дома по-пробую на линухе.
За такой ответ спасибо, так бы и сразу)
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