首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在utf-8 Python代码中使用不可编码的mp4标记名。

在utf-8 Python代码中使用不可编码的mp4标记名。
EN

Stack Overflow用户
提问于 2014-03-08 19:20:23
回答 3查看 1.6K关注 0票数 0

由于我不清楚的原因,mp4文件用作标记名的一些字段包含不可打印的字符至少是诱变剂看它们的方式。给我带来麻烦的是'\xa9wrt',它是composer字段(!?)的标记名。

如果我从Python控制台运行'\xa9wrt'.encode('utf-8'),就会得到

代码语言:javascript
复制
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa9 in position 0: invalid start byte

我试图从一个Python文件中访问这个值,该文件使用了一些未来的校对方法,包括:

代码语言:javascript
复制
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

我甚至不知道如何将字符串'\xa9wrt'输入到我的代码文件中,因为该文件中的所有内容都被解释为utf-8,而我感兴趣的字符串显然不能用utf-8编写。此外,当我将字符串'\xa9wrt'放入变量(例如,诱变器)中时,很难使用。例如,"{}".format(the_variable)失败是因为"{}"被解释为u"{}",后者再次尝试将字符串编码为utf-8。

只是天真地进入'\xa9wrt',给了我不一样的u'\xa9wrt',而且我尝试过的其他东西也都没有用:

代码语言:javascript
复制
>>> u'\xa9wrt' == '\xa9wrt'
False
>>> str(u'\xa9wrt')
'\xc2\xa9wrt'
>>> str(u'\xa9wrt') == '\xa9wrt'
False

注意,这个输出来自控制台,在这里,我确实可以输入非Unicode文本。我在Mac上使用Spyder和sys.version = 2.7.6 |Anaconda 1.8.0 (x86_64)| (default, Nov 11 2013, 10:49:09)\n[GCC 4.0.1 (Apple Inc. build 5493)]

如何在Unicode世界中使用此字符串?utf-8没有能力这么做吗?

更新:谢谢你,@tsroten,给我答案。这提高了我的理解,但我仍然无法达到我想要的效果。这里有一个更尖锐的问题:我怎样才能用‘?’到达这两条线?而不使用我所用的伎俩?

注意,我正在使用的str是由一个库传递给我的。我得接受那种类型的

代码语言:javascript
复制
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

tagname = 'a9777274'.decode('hex') # This value comes from a library as a str, not a unicode
if u'\xa9wrt' == tagname:
    # ??: What test could I run that would get me here without resorting to writing my string in hex?
    print("You found the tag you're looking for!")
else:
    print("Keep looking!")

print(str("This will work: {}").format(tagname))
try:
    print("This will throw an exception: {}".format(tagname))
    # ??: Can I reach this line without resorting to converting my format string to a str?
except UnicodeDecodeError:
    print("Threw exception")

更新2:

我不认为你(@tsroten)构造的任何字符串都与我从诱变剂中得到的字符串相等。该字符串似乎仍然会引起问题:

代码语言:javascript
复制
>>> u = u'\xa9wrt'
>>> s = u.encode('utf-8')
>>> s2 = '\xa9wrt'
>>> s3 = 'a9777274'.decode('hex')
>>> s2 == s
False
>>> s2 == s3
True
>>> match_tag(s)
We have a match! tagname == ©wrt
Look! We printed tagname and no exception was raised.
>>> match_tag(s2)
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa9 in position 0: invalid start byte
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-09 17:19:47

\xa9是版权的象征。有关更多信息,请参见Unicode标准中的C1控件和拉丁文-1补编

也许©wrt标签的意思是“版权”而不是“作曲家”?

当您运行'\xa9wrt'.encode('utf-8')时,您获得UnicodeDecodeError的原因是encode()期望unicode,但您给了它str。因此,它首先将其转换为unicode,但假设str编码是'ascii' (或其他一些默认的)。这就是为什么在编码时会出现解码错误的原因。这个问题应该通过使用unicodeu'\xa9wrt'.encode('utf-8')来解决。

默认情况下,在Python解释器中,type('')应该返回<type 'str'>。如果在解释器中首先输入from __future__ import unicode_literals,那么type('')应该返回<type 'unicode'>。你说,只是天真地进入'\xa9wrt',给了我u'\xa9wrt'__,这是不一样的。然而,你的陈述有时是正确的,有时是错误的。u'\xa9wrt' == '\xa9wrt'的计算结果是否为TrueFalse取决于您是否导入了unicode_literals

将以下内容复制、粘贴并保存到文件中(例如test.py),然后从命令行运行python test.py

代码语言:javascript
复制
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

tag1 = u'\xa9wrt'
tag2 = '\xa9wrt'
print("tag1 = u'\\xa9wrt'")
print("tag2 = '\\xa9wrt'")
print("tag1: %s" % tag1)
print("tag2: %s" % tag1)
print("type(tag1): %s" % type(tag1))
print("type(tag2): %s" % type(tag2))
print("tag1 == tag2: %s" % (tag1 == tag2))
try:
    print("str(tag1): %s" % str(tag1))
except UnicodeEncodeError:
    print("str(tag1): raises UnicodeEncodeError")
print("tag1.encode('utf-8'): ".encode('utf-8') + tag1.encode('utf-8'))

在将上面的代码复制并粘贴到文件中,然后在Python2.7中运行之后,我得到了以下输出:

代码语言:javascript
复制
tag1 = u'\xa9wrt'
tag2 = '\xa9wrt'
tag1: ©wrt
tag2: ©wrt
type(tag1): <type 'unicode'>
type(tag2): <type 'unicode'>
tag1 == tag2: True
str(tag1): raises UnicodeEncodeError
tag1.encode('utf-8'): ©wrt

编辑:

如果您的代码在内部使用unicode,您的生活就会容易得多。这意味着,当您接收到输入时,您将其转换为unicode,或者当您输出时,您将转换为str (如果需要)。因此,当您从某个地方接收到str标签名时,首先将其转换为unicode

例如,下面是test.py

代码语言:javascript
复制
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

def match_tag(tagname):
    if isinstance(tagname, str):
        # tagname comes in as str, so let's convert it
        tagname = tagname.decode('utf-8')  # enter the correct encoding here

    # Now that we have a unicode tag, we can deal with it easily:
    if tagname == '\xa9wrt':
        print("We have a match! tagname == %s" % tagname)
        print("Look! We printed tagname and no exception was raised.")

然后,我们运行它:

代码语言:javascript
复制
>>> from test import match_tag
>>> u = u'\xa9wrt'
>>> s = u.encode('utf-8')
>>> type(u)
<type 'unicode'>
>>> type(s)
<type 'str'>
>>> match_tag(u)
We have a match! tagname == ©wrt
Look! We printed tagname and no exception was raised.
>>> match_tag(s)
We have a match! tagname == ©wrt
Look! We printed tagname and no exception was raised.

因此,您需要了解输入字符串使用的编码方式。然后,您将能够将该str转换为unicode,并且您的代码会流得更好。

编辑2:

如果您只是想让s2 = '\xa9wrt'工作,那么首先需要正确地解码它。s2是一个具有默认编码的str (检查sys.getdefaultencoding()以查看哪一个--可能是ascii)。但是,\xa9不是ASCII字符,所以Python会自动转义它。这就是s2的问题所在。当将它输入match_tag()时,请尝试此方法

代码语言:javascript
复制
>>> s2 = '\xa9wrt'
>>> s2_decoded = s2.decode('unicode_escape')
>>> type(s2_decoded)  # This is unicode, just like we want.
<type 'unicode'>
>>> match_tag(s2_decoded)
We have a match! tagname == ©wrt
Look! We printed tagname and no exception was raised.
票数 1
EN

Stack Overflow用户

发布于 2014-03-13 17:00:50

字符串是用拉丁文-1编码的,所以如果要将其存储在UTF-8文件中或将其与UTF-8字符串进行比较,只需执行以下操作:

代码语言:javascript
复制
>>> '\xa9wrt'.decode('latin-1').encode('utf-8')
'\xc2\xa9wrt'

或者,如果要将其与Unicode字符串进行比较:

代码语言:javascript
复制
>>> '\xa9wrt'.decode('latin-1') == u'©wrt'
True
票数 1
EN

Stack Overflow用户

发布于 2014-03-09 16:08:05

我终于找到了一种用unicode_literals在utf-8文件中表示所讨论的字符串的方法。我将字符串转换为十六进制,然后返回。具体来说,在控制台(显然不在unicode_literals模式下)中,我运行

代码语言:javascript
复制
"".join(["{0:x}".format(ord(c)) for c in '\xa9wrt'])

然后,在源文件中,我可以创建我想要的字符串。

代码语言:javascript
复制
'a9777274'.decode('hex')

但这不可能是正确的方式,对吧?首先,如果我的控制台完全运行unicode,我不知道首先是否可以输入字符串'\xa9wrt',让Python告诉我表示字节字符串的十六进制序列。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22273891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档