花境一年生花卉有哪些?

小说:花境一年生花卉有哪些?作者:文顺公乙更新时间:2019-05-21字数:33507

朱潜又观察了片刻,只见两名士兵起身去小解,很快又回来睡觉了,营门内静悄悄的,看不见一个人影。

最新的蜀桧价格表,千万不要错过

“木遁·木锭壁。“爆炸产生的浓雾之中传出来的声音不是铁血凯,反而是大和,当烟雾被威风吹散的时候,却是看到了大和不知道什么时候出现在铁血凯的身边,并且关键时刻使出了木锭壁挡住了爆炸,不过黏土分身的自爆却是将木锭壁给完全摧毁了,不过残余的威力对于身体强壮无比的铁血凯来算根本不算什么。
安德鲁·巴尔特菲尔德说道,他真的是好奇,不是假的,事实上不止是安德鲁·巴尔特菲尔德,这个世界不管是新人类还是自然人的高层在知道刘皓他们只有几个人只有却能掀起巨大的风云还是让他们吃惊的同时也万分好奇他们是怎么做到的。

跃过木桥,为首之人回头看去,嘴角露出笑意,付出一定代价还是值得,至少保住和其他组一拼实力,大人,下一步怎么做?”

 

  在开发过程中,我们经常需要打印一些变量的值,便于调试。这个时候就会发现如果在dict list这些容器中,如果包含中文字符,不管是str类型,还是unicode类型,都打印不出来。如下:

>>> print {"name": "张三"}
{"name": "xd5xc5xc8xfd"}
>>> print {"name": u"张三"}
{"name": u"u5f20u4e09"}

  当然,作为凡人的我是在无法脑补这些十六进制的意思,每次转移一下也很麻烦,有没有办法一劳永逸呢。google了一把,发现还是有很多姿势的。

  注意:本文实验主要基于win7,Python2.7,运行环境如下

>>> import sys,locale
>>> sys.getdefaultencoding()
"ascii"
>>> locale.getdefaultlocale()
("zh_CN", "cp936")
>>> sys.stdin.encoding
"cp936"
>>> sys.stdout.encoding
"cp936"

   本文地址:http://www.cnblogs.com/xybaby/p/7854126.html

str类型的中文

  首先让我们分析一下为什么无法包含中文的container(dict list tuple)

 >>> data = {"严": 1, 2: ["如"], 3:"玉"}

>>> data
{2: ["xc8xe7"], 3: "xd3xf1", "xd1xcf": 1}
>>> print data
{2: ["xc8xe7"], 3: "xd3xf1", "xd1xcf": 1}
>>> print data[3]

   上面data在key value中包含中文,而且也有嵌套的list,后文都使用这个data

  可以看到不管是直接输出data(调用dict.__repr__),还是print data(调用dict.__str__),都无法输出中文,而是像str.__repr__的结果。即调用容器的__str__时,事实上调用的是容器元素的__repr__方法,这个很好验证:

>>> class OBJ(object):
... def __str__(self):
...    return "OBJ str"
... def __repr__(self):
...    return "OBJ repr"
...
>>> lst = [OBJ()]
>>> print lst
[OBJ repr]
>>>

  OBJ这个自定义的类,__str__ __repr__的方法实现不一样,当作为container(list)的元素时,明显调用的是OBJ.__repr__

  在stackoverflow上的一个问题print-a-list-that-contains-chinese-characters-in-python给出了答案

When you print foo, what gets printed out is str(foo).
However, if foo is a list, str(foo) uses repr(bar) for each element bar, not str(bar).

  当然,这个问题早就被人发现了,在PEP3140 str(container) should call str(item), not repr(item) ,在这个提议中,就建议在打印容器的时候,使用__str__而不是__repr__。但是被Guido(Python之父)无情的拒绝了,原因是:

Guido said this would cause too much disturbance too close to beta

  虽然提议被reject了,但是需求还是照样存在的啊,于是有了各种解决办法

第一种姿势:逐个打印

  直接print容器中的元素

>>> lst = ["张三", "李四"]
>>> print "[" + ", ".join(["asdf", "中文"]) + "]"
[asdf, 中文]
>>> for k, v in {"name": "张三"}.items():
... print k, v
...
name 张三

  对于简单的容器对象,还是很方便的,但是对于嵌套的容器对象,比如上面data的例子,就很麻烦了

第二种姿势: json dumps

  这个方法在网上推荐得较多

>>> import json
>>> dumped_data = json.dumps(data, encoding = "gbk", ensure_ascii=False)
>>> print dumped_data
{"2": ["如"], "3": "玉", "严": 1}

  可以看到,虽然打印出了中文,但是2 3都被加上了引号,感觉怪怪的

  需要注意的是上面的两个参数(encoing ensure_ascii), 这两个参数都有默认参数(encoding = "utf-8", ensure_ascii=True),跟我们这里使用的都不一样。

>>> dumped_data = json.dumps(data)
  Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:Python27.9libjson\__init__.py", line 243, in dumps
    return _default_encoder.encode(obj)
  File "D:Python27.9libjsonencoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "D:Python27.9libjsonencoder.py", line 270, in iterencode
    return _iterencode(o, 0)
UnicodeDecodeError: "utf8" codec can"t decode byte 0xc8 in position 0: invalid continuation byte

  当然,为什么这里爆出了UnicodeDecodeError,可以参考这篇文章《不想再被鄙视?那就看进来! 一文搞懂Python2字符编码》

  ensure_ascii参数也很关键

>>> dumped_data = json.dumps(data, encoding = "gbk")
>>> print dumped_data
{"2": ["u5982"], "3": "u7389", "u4e25": 1}

  python document是有描述的;

If ensure_ascii is True (the default), all non-ASCII characters in the output are escaped with uXXXX sequences, and the result is a str instance consisting of ASCII characters only.

第三种姿势: repr string_escape

>>> decoded_data = repr(data).decode("string_escape")
>>> print decoded_data
{2: ["如"], 3: "玉", "严": 1}

  既然repr的输出是十六进制的str,那么就可以使用string_escape进行转换,具体也可以参见上文

第四种姿势:PEP3140

  虽然PEP3140被reject了,但我们还是可以利用其思想吧,那就是强制调用str.__str__而不是str.__repr__

 1 class ForceStr(str):
 2     def __repr__(self):
 3         return super(ForceStr, self).__str__()
 4 
 5 def switch_container( data ):
 6     ret = None
 7     if isinstance(data, str):
 8         ret = ForceStr(data)
 9     elif isinstance(data, list) or isinstance(data, tuple):
10         ret = [switch_container(var) for var in data]
11     elif isinstance(data, dict):
12         ret = dict((switch_container(k), switch_container(v)) for k, v in data.iteritems())
13     else:
14         ret = data
15     return ret

 


>>> switched_data = switch_container(data)
>>> print switched_data
{2: [如], 3: 玉, 严: 1}
>>> switched_data
{2: [如], 3: 玉, 严: 1}

  ForceStr继承自str,然后ForceStr.__repr__调用str.__str__。然后递归将容器里面的str类型的元素替换成ForceStr。可以看到,能够顺序打印出中文,格式也没有问题

unicode类型的中文

  基本姿势于上一章节是一样的,下面直接给出答案

  同上第二种姿势

>>> udata = {u"严": 1, 2: [u"如"], 3:u"玉"}
>>> print json.dumps(udata, encoding = "gbk", ensure_ascii=False)
{"2": ["如"], "3": "玉", "严": 1}

  同上第三种姿势

>>> print repr(udata).decode("unicode_escape")
{2: [u"如"], 3: u"玉", u"严": 1}
>>>

  同上第四种姿势

 1 def switch_container( data ):
 2     ret = None
 3     if isinstance(data, unicode):
 4         ret = ForceStr(data.encode(sys.stdout.encoding))
 5     elif isinstance(data, list) or isinstance(data, tuple):
 6         ret = [switch_container(var) for var in data]
 7     elif isinstance(data, dict):
 8         ret = dict((switch_container(k), switch_container(v)) for k, v in data.iteritems())
 9     else:
10         ret = data
11     return ret

>>>
>>> print switch_container(udata)
{2: [如], 3: 玉, 严: 1}

当str与unicode中文并存时

同上第二种姿势

>>> data[4] = u"啊"
>>> print json.dumps(data, encoding = "gbk", ensure_ascii=False)
{"2": ["如"], "3": "玉", "4": "啊", "严": 1}

同上第三种姿势

>>> print repr(data).decode("string_escape")
{2: ["如"], 3: "玉", 4: u"u554a", "严": 1}

  呃,unicode中文打印不出来

>>> print repr(data).decode("unicode_escape")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: "gbk" codec can"t encode character u"xc8" in position 6: illegal multibyte sequence
>>>

  擦,也许有正确的姿势,不过我没有试出来

  同上第四种姿势

 1 def switch_container( data ):
 2     ret = None
 3     if isinstance(data, str):
 4         ret = ForceStr(data)
 5     elif isinstance(data, unicode):
 6         ret = ForceStr(data.encode(sys.stdout.encoding))
 7     elif isinstance(data, list) or isinstance(data, tuple):
 8         ret = [switch_container(var) for var in data]
 9     elif isinstance(data, dict):
10         ret = dict((switch_container(k), switch_container(v)) for k, v in data.iteritems())
11     else:
12         ret = data
13     return ret

>>> print switch_container(data)
{2: [如], 3: 玉, 4: 啊, 严: 1}

总结

  json.dumps版本还算可以,能够处理str中文,unicode中文, str与unicode中文并存三种情况,不过显示结果与真实有点差异

  string_escape(unicode_escape)只使用只有str(unicode)中文的情况,使用较为受限

  自己实现的switch_container版本,能够友好支持str中文,unicode中文,str与unicode中文并存三种情况

  str与unicode并存真是一件蛋疼的事情!

reference

print-a-list-that-contains-chinese-characters-in-python

不想再被鄙视?那就看进来! 一文搞懂Python2字符编码

 

编辑:道成顺徒

发布:2019-05-21 01:41:43

当前文章:http://scycxh.com/news/20190122234.html

6公分紫薇报价哪里最低? 荷花种根多少钱一棵? 吉林有种植金叶榆的基地吗? 美人蕉今年市场什么价格? 卫矛哪里有? 求购白玉兰去哪家最好? 月季最好的品种是什么?喜欢就是最好,不喜欢再好也没用。 【知识点】果岭草是什么草,高度,常绿期,种植都在这里

22214 65049 87526 21140 93149 82035 24741 82618 44590 74889 92345 82195 60754 44529 57629 37166 69606 30209 62067 92640

我要说两句: (0人参与)

发布