【问题标题】:Python unicode os.listdir() not returning results from APIPython unicode os.listdir() 未从 API 返回结果
【发布时间】:2018-01-06 01:19:54
【问题描述】:

我正在使用 TMDb 根据文件名查找媒体。大多数情况下,这工作正常,除非我使用 os.listdir() 搜索名称中包含 Unicode 字符的文件。 As far as I can tell,TMDb 以 unicode 形式查找结果,并以 unicode 形式返回响应。

Amélie 的封面艺术文件为例:

Amélie.jpg

一个简单的对照实验表明,无论我尝试什么,它在使用键入的 Unicode 字符串时都有效,但在使用 os.listdir() 时无效。

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

import os
import tmdbsimple as tmdb

tmdb.API_KEY = '<your-key-here>'

print os.listdir('/media/artwork/')
print os.listdir(u'/media/artwork/')

print('\nstr controlled test')
s = tmdb.Search()
s.movie(query='Amélie')
print('Results', len(s.results))
for r in s.results:
    print(r)  

print('\nunicode controlled test')
s = tmdb.Search()
s.movie(query=u'Amélie')
print('Results', len(s.results))
for r in s.results:
    print(r)  

print('\nstr listdir')
for file in os.listdir('/media/artwork/'):
    s = tmdb.Search()
    s.movie(query=os.path.splitext(file)[0])
    print('Results', len(s.results))
    for r in s.results:
        print(r)

print('\nunicode listdir')
for file in os.listdir(u'/media/artwork/'):
    s = tmdb.Search()
    s.movie(query=os.path.splitext(file)[0])
    print('Results', len(s.results))
    for r in s.results:
        print(r)

输出:

['Ame\xcc\x81lie.jpg']
['u'Ame\u0301lie.jpg']

str controlled test
('Results', 8)
{u'poster_path': u'/pM20xF4WFyX7G3ie0YBXFp75aEC.jpg', u'title': u'Am\xe9lie' ... }

unicode controlled test
('Results', 8)
{u'poster_path': u'/pM20xF4WFyX7G3ie0YBXFp75aEC.jpg', u'title': u'Am\xe9lie' ... }

str listdir
('Results', 0)

unicode listdir
('Results', 0)

那么为什么原始字符串始终有效,ASCII 或 Unicode,而从文件系统中提取的文件名却不是?

我试过了:

  • encode('utf-8') 和 decode('utf-8') 的各种组合
  • 在所有文件加载中使用 u'' 前缀
  • 使用 utf-8 编码重新加载 sys
  • 我看到了来自 Martijn Pieters 的一篇关于 Mac OS 以不同方式处理 Unicode 的帖子,但我似乎再也找不到它了
  • isinstance(file, str)(惊喜,它不是 unicode!)

那么...如何让文件夹枚举与 unicode 字符一起使用,或者是否有适当的方法可以将这些 ascii 文件名转换为 unicode 而不会出现可怕的ordinal out of range 错误?

【问题讨论】:

  • 简化您的问题可能会更好,因为它似乎与 TMDb 没有任何关系。简单地列出一个带有 unicode 字符的文件似乎就足够了。似乎与stackoverflow.com/questions/26732985/utf-8-and-os-listdir 重复?
  • 这是我从 Martijn 那里丢失的问题。我会检查一下。 Fwiw,不,越简单越好,因为我还不确定这是否与 Unicode 有关。
  • UTF-8 and os.listdir()的可能重复

标签: python macos python-2.7 unicode


【解决方案1】:

不同之处在于您的文件系统使用的是分解的 Unicode 字符。如果您将返回的文件名规范化为组合的 Unicode 字符,那么\xe9 是 Unicode 字符 é 将起作用。 e\u0301 是一个 ASCII e 后跟一个组合重音符号:

>>> u'Am\xe9lie' == ud.normalize('NFC',u'Ame\u0301lie')
True

所以使用:

import unicodedata as ud
print('\nunicode listdir')
for filename in os.listdir(u'/media/artwork/'):
    nfilename = ud.normalize(filename)
    s = tmdb.Search()
    s.movie(query=os.path.splitext(nfilename)[0])
    print('Results', len(s.results))
    for r in s.results:
        print(r)

【讨论】:

  • 是的,看起来这就是关键。在 Windows 或 *nix 上运行时有什么影响?这会失败吗?
  • @brandonscript 不,您可以规范化已经规范化的字符串,因此上述代码应该适用于任何操作系统。
猜你喜欢
  • 2021-04-26
  • 2017-01-16
  • 1970-01-01
  • 2017-05-20
  • 2018-08-14
  • 1970-01-01
  • 2017-01-23
  • 2013-04-23
  • 1970-01-01
相关资源
最近更新 更多