如何在Python中将unicode对象转换为普通对象

0 投票
2 回答
1622 浏览
提问于 2025-04-16 03:00

我现在有一个很复杂的对象,里面全是unicode(真让人头疼)。

我遇到的情况是,一个变量要么是字典,要么是布尔值。在这种情况下,我会这样写:

if type( my_variable ) is BooleanType:

但是这个判断没有生效,因为所有的值实际上都是unicode类型。

我该如何把这个unicode对象转换成正常的对象,这样我就能正确判断类型,而又不破坏数据呢?

谢谢!

这是我用print(repr(variable))得到的结果。它显示布尔值并不是unicode(和我最开始想的不一样),但仍然让我遇到麻烦。

{u'forms': {u'financing': {u'view': True, u'delete': True}, u'employment': {u'view': True, u'delete': True}, u'service': {u'view': True, u'delete': True}}, u'content': {u'articles': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'slideshow': {u'edit': True, u'view': True}, u'pages': {u'edit': True, u'add': True, u'view': True, u'delete': True}}, u'people': {u'edit': True, u'sort-staff': True, u'sort-riders': True, u'add': True, u'delete': True, u'view': True}, u'events': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'settings': {u'edit': True, u'view': True}}

2 个回答

0

也许你应该了解一下“漂亮打印”模块,因为它可以帮助你检查一些问题(我也同意你把自己搞得很乱。这通常是因为递归出错,比如在应该用扩展(extend)的时候却用了添加(append)来处理列表)。

这里是你的变量内容的漂亮打印结果:

{u'content': {u'articles': {u'add': True,
                            u'delete': True,
                            u'edit': True,
                            u'view': True},
              u'pages': {u'add': True,
                         u'delete': True,
                         u'edit': True,
                         u'view': True},
              u'slideshow': {u'edit': True, u'view': True}},
 u'events': {u'add': True, u'delete': True, u'edit': True, u'view': True},
 u'forms': {u'employment': {u'delete': True, u'view': True},
            u'financing': {u'delete': True, u'view': True},
            u'service': {u'delete': True, u'view': True}},
 u'people': {u'add': True,
             u'delete': True,
             u'edit': True,
             u'sort-riders': True,
             u'sort-staff': True,
             u'view': True},
 u'settings': {u'edit': True, u'view': True}}

从这里可以看出,你只有 True 的值,而没有 False。那这些值有什么用呢?为什么不使用集合(set)呢,比如:{u'add',u'delete', u'edit', u'sort-riders',...}?

from pprint import pprint

def alternative(yourdict):
    for key in yourdict:
        if yourdict[key] is True:
            yield set(yourdict.keys())
            break
        else:
            yield tuple((key,tup) for tup in alternative(yourdict[key]))

my_variable = {u'forms': {u'financing': {u'view': True, u'delete': True}, u'employment': {u'view': True, u'delete': True}, u'service': {u'view': True, u'delete': True}}, u'content': {u'articles': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'slideshow': {u'edit': True, u'view': True}, u'pages': {u'edit': True, u'add': True, u'view': True, u'delete': True}}, u'people': {u'edit': True, u'sort-staff': True, u'sort-riders': True, u'add': True, u'delete': True, u'view': True}, u'events': {u'edit': True, u'add': True, u'view': True, u'delete': True}, u'settings': {u'edit': True, u'view': True}}
pprint(my_variable)

print 50 * '-'
print 'Alternative datastructure'
pprint(tuple(alternative(my_variable)))
1

除非你非常非常确定,否则不要使用 type

在这个情况下,你其实不需要使用它,特别是当你要检查 bool 类型时,因为Python在什么可以被认为是布尔值方面非常灵活!比如说,如果你得到的是 None 呢?那空字符串呢?还有 [] 呢?

解决这个问题的方法是使用抽象基类(ABCs),它们可以让你明确指定一个对象应该具备哪些功能,而不是它的具体类型。collections 模块里有很多这样的类:

import collections
if isinstance( ..., collections.MutableMapping ):
    ...

这允许任何“像字典一样”的东西,这样你就可以保持多态性。如果你需要更仔细的规定(“我想要 __getitem____delitem__,但不一定需要 __setitem__!”),你可以自己写一个——可以先看看 collections 模块源代码里的 ABC 定义。

你确定你想要这个功能吗?如果你正确使用(用 ABCs),这并不是一个坏主意,但这并不意味着你可以随意使用它!


编辑:我不太确定你是否理解什么是Unicode,或者Python是如何处理它的。这是Python 2.x和Python 3.x之间的主要区别之一,你在用哪个版本?

重新编辑:哦,明白了,你在用Python 2.x,并且你的字典里有Unicode字符串作为键。我不太清楚你在做什么导致了问题,因为Unicode字符串基本上和普通字符串一样工作。上面的 MutableMapping 检查会正常工作。

撰写回答