Python:如何将shutil.copy()与unicode文件名一起使用

Python:如何将shutil.copy()与unicode文件名一起使用,python,unicode,Python,Unicode,所以我一直在为这个问题绞尽脑汁好几天了,我就是想不出来。我读过书,觉得我一定错过了什么 我正在尝试使用以下代码将带有复杂unicode标题的简单文本文件复制到临时文件夹中: self._temp_path = tempfile.mkdtemp() self.src = os.path.join(self._temp_path, 'src') os.makedirs(self.src) self.dst = os.path.join(self._temp_path, 'dst') os.maked

所以我一直在为这个问题绞尽脑汁好几天了,我就是想不出来。我读过书,觉得我一定错过了什么

我正在尝试使用以下代码将带有复杂unicode标题的简单文本文件复制到临时文件夹中:

self._temp_path = tempfile.mkdtemp()
self.src = os.path.join(self._temp_path, 'src')
os.makedirs(self.src)
self.dst = os.path.join(self._temp_path, 'dst')
os.makedirs(self.dst)
self.dirname = dirname = os.path.join(os.path.dirname(__file__), 'testfiles')
f = u'file-\xe3\x82\xa8\xe3\x83\xb3\xe3\x83\x89\xe3\x83\xac\xe3\x82\xb9.txt'
src = os.path.join(dirname, f)
dst = os.path.join(self.src, f)
shutil.copy2(src, dst)
当我执行测试时,我收到以下消息:

s = '/tmp/tmpc1gzwf/src/file-ã¨ã³ãã¬ã¹.txt'
>           st = os.stat(s)
E           UnicodeEncodeError: 'ascii' codec can't encode characters in position 24-38: ordinal not in range(128)
我尝试过使用shutil.copy和shutil.copy2,它们产生了相同的结果。我也尝试过改变:

shutil.copy2(src, dst)
致:

但由于编码损坏了文件名,导致出现此错误消息:

src = '/home/phil/projects/unicode_copy/tests/testfiles/file-\xc3\xa3\xc2\x82\xc2\xa8\xc3\xa3\xc2\x83\xc2\xb3\xc3\xa3\xc2\x83\xc2\x89\xc3\xa3\xc2\x83\xc2\xac\xc3\xa3\xc2\x82\xc2\xb9.txt'
dst = '/tmp/tmpCsb3qW/src/file-\xc3\xa3\xc2\x82\xc2\xa8\xc3\xa3\xc2\x83\xc2\xb3\xc3\xa3\xc2\x83\xc2\x89\xc3\xa3\xc2\x83\xc2\xac\xc3\xa3\xc2\x82\xc2\xb9.txt'
def copyfile(src, dst):
...
>       with open(src, 'rb') as fsrc:
E       IOError: [Errno 2] No such file or directory: '/home/phil/projects/unicode_copy/tests/testfiles/file-\xc3\xa3\xc2\x82\xc2\xa8\xc3\xa3\xc2\x83\xc2\xb3\xc3\xa3\xc2\x83\xc2\x89\xc3\xa3\xc2\x83\xc2\xac\xc3\xa3\xc2\x82\xc2\xb9.txt'

在代码中的不同位置尝试了许多其他的encode()和decode()组合之后,我放弃了。声明unicode文件名并将其传递给shutil.copy的正确方法是什么?

我在我的系统上根据您的代码快速运行了以下代码,它似乎工作正常:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import shutil
import tempfile

from pathlib import Path


class Code():

    def run(self):
        self._temp_path = Path(tempfile.mkdtemp())
        self.dstdir = self._temp_path / 'dst'
        os.makedirs(self.dstdir)

        self.srcdir = Path(os.path.dirname(__file__)) / 'testfiles'
        filename = u'file-\xe3\x82\xa8\xe3\x83\xb3\xe3\x83\x89\xe3\x83\xac\xe3\x82\xb9.txt'

        self.srcpath = self.srcdir / filename
        self.dstpath = self.dstdir / filename

        with open(self.srcpath, 'w') as f:
            f.write('test')

        shutil.copy2(self.srcpath, self.dstpath)


if __name__ == '__main__':
    code = Code()
    code.run()
    print(code.dstpath)
样本输出为
/tmp/tmpgqwktb_v/dst/file-ã

可能的原因是:

  • 我使用的是Python3,它对unicode的支持明显更好
  • 我在en_GB.UTF-8语言环境中运行Linux
  • 脚本的第二行,声明源代码的编码
也许与您的环境的差异可以解释您的错误


希望这有帮助

您确定文件名不是
”文件吗-エンドレス.txt'
?您可以尝试使用
os.listdir(src)
,它将为您提供src目录中的所有文件。这将允许您选择文件,而无需在名称中明确写入。谢谢您,先生!从未想过检查我的环境变量。原来我登录的用户将LANG设置为POSIX。。。将其切换到en_US.UTF-8,现在代码运行完美。我很高兴!编码和区域设置有时很难处理。不要总是配置UTF-8(当然,如果这符合您的目的的话),这样您将省去很多麻烦事。:-)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import shutil
import tempfile

from pathlib import Path


class Code():

    def run(self):
        self._temp_path = Path(tempfile.mkdtemp())
        self.dstdir = self._temp_path / 'dst'
        os.makedirs(self.dstdir)

        self.srcdir = Path(os.path.dirname(__file__)) / 'testfiles'
        filename = u'file-\xe3\x82\xa8\xe3\x83\xb3\xe3\x83\x89\xe3\x83\xac\xe3\x82\xb9.txt'

        self.srcpath = self.srcdir / filename
        self.dstpath = self.dstdir / filename

        with open(self.srcpath, 'w') as f:
            f.write('test')

        shutil.copy2(self.srcpath, self.dstpath)


if __name__ == '__main__':
    code = Code()
    code.run()
    print(code.dstpath)