7

我在 Windows 下的 Python 脚本中的 unicode 命名文件夹之间移动一个 unicode 命名文件时遇到了麻烦......

您将使用什么语法在文件夹中查找所有 *.ext 类型的文件并将它们移动到相对位置?

假设文件和文件夹是 unicode。

4

2 回答 2

15

基本问题是 Unicode 和字节字符串之间的未转换混合。解决方案可以转换为单一格式或使用一些技巧来避免问题。glob我所有的解决方案都包括shutil标准库。

例如,我有一些以 Unicode 文件名结尾的文件名ods,我想将它们移动到名为א(Hebrew Aleph,一个 unicode 字符)的子目录中。

第一个解决方案 - 将目录名称表示为字节字符串:

>>> 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(),然后通过将其引用为.

# -*- 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 buglist 中的一个问题,并等待回复。

进一步阅读

Python 的官方 Unicode HOWTO

于 2011-04-02T13:18:27.277 回答
3

到处使用 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().

于 2011-04-02T16:47:51.013 回答