Python: как перенести файл с файлом unicode в папку юникода

У меня ад с перемещением unicode с именем file между unicode именованными папками в скрипте Python под Windows …

Какой синтаксис вы бы использовали, чтобы найти все файлы типа * .ext в папке и перенести их в относительное местоположение?

Предположим, что файлы и папки являются unicode.

    Основная проблема заключается в непрореагировавшем соединении между строками Unicode и байтов. Решения могут преобразовываться в один формат или избегать проблем, используя некоторые обманы. Все мои решения включают стандартную библиотеку glob и shutil .

    Например, у меня есть некоторые имена файлов Unicode, заканчивающиеся на ods , и я хочу переместить их в подкаталог под названием א (Hebrew Aleph, символ Юникода).

    Первое решение – выразить имя каталога в виде строки байта:

     >>> import glob >>> import shutil >>> files=glob.glob('*.ods') # List of Byte string file names >>> for file in files: ... shutil.copy2(file, 'א') # Byte string directory name ... 

    Второе решение – конвертировать имена файлов в Unicode:

     >>> import glob >>> import shutil >>> files=glob.glob(u'*.ods') # List of Unicode file names >>> for file in files: ... shutil.copy2(file, u'א') # Unicode directory name 

    Благодарим Ezio Melotti, список ошибок Python .

    Третье решение – исключение названия каталога Unicode

    Хотя это не лучшее решение, на мой взгляд, здесь есть хороший трюк, о котором стоит упомянуть.

    Измените свой каталог на целевой каталог с помощью os.getcwd() , а затем скопируйте файлы на него, os.getcwd() его как . :

     # -*- coding: utf-8 -*- import os import shutil import glob os.chdir('א') # CD to the destination Unicode directory print os.getcwd() # DEBUG: Make sure you're in the right place files=glob.glob('../*.ods') # List of Byte string file names for file in files: shutil.copy2(file, '.') # Copy each file # Don't forget to go back to the original directory here, if it matters 

    Более глубокое объяснение

    Прямой подход shutil.copy2(src, dest) терпит неудачу, потому что shutil объединяет unicode со строкой ASCII без конверсий:

     >>> files=glob.glob('*.ods') >>> for file in files: ... shutil.copy2(file, u'א') ... Traceback (most recent call last): File "<stdin>", line 2, in <module> File "/usr/lib/python2.6/shutil.py", line 98, in copy2 dst = os.path.join(dst, os.path.basename(src)) File "/usr/lib/python2.6/posixpath.py", line 70, in join path += '/' + b UnicodeDecodeError: 'ascii' codec can't decode byte 0xd7 in position 1: ordinal not in range(128) 

    Как видно ранее, этого можно избежать при использовании 'א' вместо Unicode u'א'

    Это ошибка?

    На мой взгляд, это ошибка, потому что Python не может ожидать, что имена basedir всегда будут str , а не unicode . Я сообщил об этом как о проблеме в биг-листе Python и ожидаю ответов.

    дальнейшее чтение

    Официальный язык Python Unicode HOWTO

    Используйте строку Unicode везде:

     # -*- coding: utf-8 -*- # source code ^^ encoding; it might be different from sys.getfilesystemencoding() import glob import os srcdir = u'مصدر الدليل' # <-- unicode string dstdir = os.path.join('..', u'κατάλογο προορισμού') # relative path for path in glob.glob(os.path.join(srcdir, u'*.ext')): newpath = os.path.join(dstdir, os.path.basename(path)) os.rename(path, newpath) # move file or directory; assume the same filesystem 

    В движущихся файлах много тонких деталей; см. функции shutit.copy* . Вы можете использовать тот, который подходит в вашем конкретном случае, и удалять исходные файлы при успешном выполнении, например, через os.remove() .