crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Копирование файлов в Питоне
Litkevich Yuriy
  опции профиля:
сообщение 16.5.2011, 10:30
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9649
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Задача, скопировать несколько файлов в некий каталог.

Подводные камни:
* имя исходного файла относительно текущего каталога
* имя исходного файла содержит кириллицу
* имя исходного файла содержит пробелы

структура ФС:
-doc
-folder_1/file раз.txt
-folder_1/file два.txt
-folder два/file раз.txt
-folder два/file 2.txt


нужно все файлы скопировать в каталог doc

Код для теста наваял такой:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# тест

import sys
import shutil
import os


docs = ["\"folder_1/file раз.txt\"",
"\"folder_1/file два.txt\"",
"\"folder два/file два.txt\"",
"\"folder два/file 2.txt\""]

destDir = "doc"



def copyDocs():
    if os.path.isdir(destDir):
        print '\'' + destDir + '\'' + ' is Dir'
    for doc in docs:
        if os.path.exists(doc):
            print doc + ' is exists!'
        else:
            print doc + ' is NOT exists!'
        #file = os.path.basename(doc)
        #shutil.copy(doc, destDir)

if __name__ == '__main__':
    copyDocs()

К консоли винды получаю такое:
'doc' is Dir
"folder_1/file ╤А╨░╨╖" is NOT exists!
"folder_1/file ╨┤╨▓╨░" is NOT exists!
"folder ╨┤╨▓╨░/file ╨┤╨▓╨░╨н" is NOT exists!
"folder ╨┤╨▓╨░/file 2" is NOT exists!

В IDLE:
'doc' is Dir
"folder_1/file раз.txt" is NOT exists!
"folder_1/file РґРІР°.txt" is NOT exists!
"folder два/file дваЭ.txt" is NOT exists!
"folder РґРІР°/file 2.txt" is NOT exists!

А вот если не изменяя самого исходника, поменять кодировку файла на ANSI (т.е. и запись о кодировке UTF-8 оставить неизменной)
то вывод в IDLE будет:
'doc' is Dir
"folder_1/file раз.txt" is NOT exists!
"folder_1/file два.txt" is NOT exists!
"folder два/file два.txt" is NOT exists!
"folder два/file 2.txt" is NOT exists!

Т.е. выводится корректный текст, но файлы всё-равно не видит.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 16.5.2011, 19:48
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Так ты же кавычки в имя файла запихал

# -*- coding: utf-8 -*-

import os

docs = ['folder_1/file раз.txt',
        'folder_1/file два.txt',
        'folder два/file раз.txt',
        'folder два/file 2.txt'
       ]

for doc in docs:
    if os.path.exists(doc):
        print doc, 'is exist!'
    else:
        print doc, 'is NOT exist!'


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 16.5.2011, 19:52
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9649
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(igor_bogomolov @ 16.5.2011, 22:48) *
Так ты же кавычки в имя файла запихал
дык, я полагал, что они неотемлемы при пробелах.

Прийду завтра на работу проверю твой вариант
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 17.5.2011, 5:41
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9649
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


вот к чему привёл метод научного тыка:
* экранированные кавычки - ненужны.
* если кодировка исходника CP1251, то всё корректно работает с кириллицей, не взирая на то, что в начале файла есть запись о кодировке UTF-8.

Но надо бы делать по правильному - заявленная кодировка должна соответствовать реальной.
в случае с Qt, можно было бы воспользоваться QObject::trUtf8(). Однако питону явно указано в какой кодировке файл.

Тут я что-то совсем не пойму.

П.С.
Питон 2.6
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 17.5.2011, 12:10
Сообщение #5


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Litkevich Yuriy @ 17.5.2011, 6:41) *
* экранированные кавычки - ненужны.
Ну это мы уже выяснили.
Цитата(igor_bogomolov @ 16.5.2011, 20:48) *
Так ты же кавычки в имя файла запихал
Было бы странно, если бы они были нужны. Мы же не в консоли команду вводим.
Ты же не делаешь в Qt так:
#include <QtCore>                                                                                                                            
                                                                                                                                            
int main(int argc, char **argv)                                                                                                              
{                                                                                                                                            
    QCoreApplication app(argc, argv);                                                                                                        
    QFile file("\"file name.txt\"");                                                                                                        
    if (file.exists())                                                                                                                      
        qDebug("file (%s) is exist!", qPrintable(file.fileName()));                                                                          
    else                                                                                                                                    
        qDebug("file (%s) is NOT exist!", qPrintable(file.fileName()));                                                                      
                                                                                                                                    
    return 0;                                                                                                                                
}
Такой код тоже файла не найдет, даже если он существует. Все по тем же причинам (кавычки в имени файла).

Цитата(Litkevich Yuriy @ 17.5.2011, 6:41) *
* если кодировка исходника CP1251, то всё корректно работает с кириллицей, не взирая на то, что в начале файла есть запись о кодировке UTF-8.
Но надо бы делать по правильному - заявленная кодировка должна соответствовать реальной.
Так если у тебя файл в кодировке cp1251, почему интерпретатору ты говоришь иначе? Пиши так
# -*- coding: cp1251 -*-


Ну и что бы завершить тему. Представим ситуацию. Файл у нас в кодировке cp1251. Система/консоль в UTF8.
# -*- coding: cp1251 -*-
import os
file_name = 'file один.txt'
if os.path.exists(file_name):
    print file_name, 'is exist!'
else:
    print file_name, 'is NOT exist!'
Этот код не найдет существующий файл. К тому же на консоль выведет кракозябры. Что бы всё работало так как задумано , нужно писать так
file_name = 'file один.txt'.decode('cp1251')

Но это надуманный пример. В реальной ситуации такого быть не должно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 19.5.2011, 7:07
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9649
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(igor_bogomolov @ 17.5.2011, 15:10) *
Так если у тебя файл в кодировке cp1251, почему интерпретатору ты говоришь иначе?
потому-что он изначально был в UTF-8

Цитата(igor_bogomolov @ 17.5.2011, 15:10) *
file_name = 'file один.txt'.decode('cp1251')
пример не понял. В какой кодировке исходник?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 19.5.2011, 14:27
Сообщение #7


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Litkevich Yuriy @ 19.5.2011, 8:07) *
пример не понял. В какой кодировке исходник?
В cp1251. В сообщении дважды это указано, на словах и в коде

Цитата('Litkevich Yuriy' date='19.5.2011 @ 8:07' post=49834)
потому-что он изначально был в UTF-8
Что то ты запутался в кодировках и меня запутал.
В общем так. Если ты используешь кириллицу в файле *.py, ты должен явно указывать кодировку этого файла. Делается это так: # -*- coding: cp1251 -*-. Далее, если у тебя кодировка консоли (это пример) отличается от кодировки исходников, при выводе сообщения с кириллицей на экран ты увидишь просто набор не читаемых символов. Если ты хочешь увидеть реальное сообщение делай так
print 'Здесь должен быть текст на Русском в кодировке ibm866'.decode('ibm866')

Поэкспериментируй немного с функцией decode и кодировками файла и все встанет на свои места.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 19.5.2011, 16:43
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9649
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(igor_bogomolov @ 19.5.2011, 17:27) *
Что то ты запутался в кодировках и меня запутал.
я изначально написал исходник в кодировке utf-8 и соответсвующим образом пометил во второй строке файла.

Цитата(igor_bogomolov @ 19.5.2011, 17:27) *
Если ты хочешь увидеть реальное сообщение делай так
print 'Здесь должен быть текст на Русском в кодировке ibm866'.decode('ibm866')

Поэкспериментируй немного с функцией decode и кодировками файла и все встанет на свои места.
а если я не хочу вывода в консоль, а просто копирую файлы? всё равно нужно использовать decode()?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 19.5.2011, 23:17
Сообщение #9


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(Litkevich Yuriy @ 19.5.2011, 17:43) *
а если я не хочу вывода в консоль, а просто копирую файлы? всё равно нужно использовать decode()?
В твоём случае - да.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 12.12.2018, 4:01