1.トゥカオ問題
あなたはpprintに精通しているべきですよね?
検索エンジンで美しい辞書やフォーマット文字列を印刷する方法を検索するときは、ほとんどの人がこの製品の使用をお勧めします。
たとえば、次のjson文字列または辞書(インターネットで見つけました)は、フォーマットおよび美化されていないと、まったく読み取ることができません。
[{"id":1580615,"name":"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":"2011-2017 你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":"斗鱼271934 走过路过不要错过,这里有最好的鸡儿"}]
密集した単語をたくさん見たくない場合は、誰もが強く推奨するpprintを使用して、効果を確認してください(以下は、Python 2で示されていますが、Python 3では効果が異なります)。
>>> info=[{"id":1580615,"name":"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":"2011-2017 你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":"斗鱼271934 走过路过不要错过,这里有最好的鸡儿"}]
>>>
>>> from pprint import pprint
>>> pprint(info)
[{'des': '2011-2017 \xe4\xbd\xa0\xe7\x9a\x84\xe9\x93\x81\xe5\xa4\xb4\xe5\xa8\x83\xe4\xb8\x80\xe7\x9b\xb4\xe5\x9c\xa8\xe8\xbf\x99\xe5\x84\xbf\xe3\x80\x82\xe4\xb8\xad\xe5\x9b\xbd\xe6\x9c\x80\xe5\xa4\xa7\xe7\x9a\x84\xe5\xae\x9e\xe5\x90\x8d\xe5\x88\xb6SNS\xe7\xbd\x91\xe7\xbb\x9c\xe5\xb9\xb3\xe5\x8f\xb0\xef\xbc\x8c\xe5\xab\xa9\xe5\xa4\xb4\xe9\x9d\x92',
'downloadUrl': 'app/com.renren.mobile.android/com.renren.mobile.android.apk',
'iconUrl': 'app/com.renren.mobile.android/icon.jpg',
'id': 1580615,
'name': '\xe7\x9a\xae\xe7\x9a\x84\xe5\x98\x9b',
'packageName': 'com.renren.mobile.android',
'size': 21803987,
'stars': 2},
{'des': '\xe6\x96\x97\xe9\xb1\xbc271934 \xe8\xb5\xb0\xe8\xbf\x87\xe8\xb7\xaf\xe8\xbf\x87\xe4\xb8\x8d\xe8\xa6\x81\xe9\x94\x99\xe8\xbf\x87\xef\xbc\x8c\xe8\xbf\x99\xe9\x87\x8c\xe6\x9c\x89\xe6\x9c\x80\xe5\xa5\xbd\xe7\x9a\x84\xe9\xb8\xa1\xe5\x84\xbf',
'downloadUrl': 'app/com.ct.client/com.ct.client.apk',
'iconUrl': 'app/com.ct.client/icon.jpg',
'id': 1540629,
'name': '\xe4\xb8\x8d\xe5\xad\x98\xe5\x9c\xa8\xe7\x9a\x84',
'packageName': 'com.ct.client',
'size': 4794202,
'stars': 2}]
効果があるようですが、実は「アーティファクト」です。
しかし、教えてください、これらの\ xe4 \ xbd \ xa0 \ xe7 \ x9aは何ですか?読みやすさを向上させたかったのは、今では完全に読めません。
幸い、Python 2のエンコーディングについて少し知っています。Python2のデフォルトの文字列形式(uなし)はstr型であり、これもbytes型であり、bytesで格納されます。
さて、私は間違っていたようです、私はそれを変更し、ユニコードタイプを使用して中国語の文字列を定義しました。
>>> info = [{"id":1580615,"name":u"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]
>>>
>>> from pprint import pprint
>>> pprint(info)
[{'des': u'2011-2017\u4f60\u7684\u94c1\u5934\u5a03\u4e00\u76f4\u5728\u8fd9\u513f\u3002\u4e2d\u56fd\u6700\u5927\u7684\u5b9e\u540d\u5236SNS\u7f51\u7edc\u5e73\u53f0\uff0c\u5ae9\u5934\u9752',
'downloadUrl': 'app/com.renren.mobile.android/com.renren.mobile.android.apk',
'iconUrl': 'app/com.renren.mobile.android/icon.jpg',
'id': 1580615,
'name': u'\u76ae\u7684\u561b',
'packageName': 'com.renren.mobile.android',
'size': 21803987,
'stars': 2},
{'des': u'\u6597\u9c7c271934\u8d70\u8fc7\u8def\u8fc7\u4e0d\u8981\u9519\u8fc7\uff0c\u8fd9\u91cc\u6709\u6700\u597d\u7684\u9e21\u513f',
'downloadUrl': 'app/com.ct.client/com.ct.client.apk',
'iconUrl': 'app/com.ct.client/icon.jpg',
'id': 1540629,
'name': u'\u4e0d\u5b58\u5728\u7684',
'packageName': 'com.ct.client',
'size': 4794202,
'stars': 2}]
確かに良いのですが、次のことを見て倒れました。これが一体何なのか、どこでわかるのでしょうか。私がコンピューターのときは?
u'\u6597\u9c7c271934\u8d70\u8fc7\u8def\u8fc7\u4e0d\u8981\u9519\u8fc7\uff0c\u8fd9\u91cc\u6709\u6700\u597d\u7684\u9e21\u513f'
さらに、jsonの厳格な要件では二重引用符を使用する必要があることはわかっていますが、辞書を定義するときに二重引用符を使用するのに、なぜ一重引用符を印刷するのですか?難しすぎて自分のコードをコントロールすることもできますか?
この時点で、pprintがもたらす2つの問題がわかっています。
- Python2では正常に中国語を印刷できません
- フォーマットされたコンテンツをJSON標準フォーマットで出力できません(二重引用符)
2.問題を解決する
中国語を印刷
Python 3で使用している場合は、中国語を正常に表示できることがわかります。
# Python3.7
>>> info = [{"id":1580615,"name":u"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]
>>>
>>> from pprint import pprint
>>> pprint(info)
[{'des': '2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青',
'downloadUrl': 'app/com.renren.mobile.android/com.renren.mobile.android.apk',
'iconUrl': 'app/com.renren.mobile.android/icon.jpg',
'id': 1580615,
'name': '皮的嘛',
'packageName': 'com.renren.mobile.android',
'size': 21803987,
'stars': 2},
{'des': '斗鱼271934走过路过不要错过,这里有最好的鸡儿',
'downloadUrl': 'app/com.ct.client/com.ct.client.apk',
'iconUrl': 'app/com.ct.client/icon.jpg',
'id': 1540629,
'name': '不存在的',
'packageName': 'com.ct.client',
'size': 4794202,
'stars': 2}]
>>>
しかし、多くの場合(会社のサーバーの一部では)、使用するPythonのバージョンを選択できません。より良い代替手段があるため、使用しないことを選択できます(これについては後で説明します)。
でも好奇心から、2日前にコーディングの記事を書いただけじゃなかったのでしょうか?コーディングはかなり上手だと思うので、この問題を解決したいと思います。
pprintのソースコードを見てください。私は本当に解決策を見つけました。挑戦したい場合は、ここで停止して、自分で実装する方法を勉強してください。ソースコードを読むと役立つと思います。
以下はあなたの参照のための私の解決策です:
PrettyPrinter(pprintで使用されるプリンター)から継承された独自のプリンターオブジェクトを作成します
そして、formatメソッドを上書きして、渡された文字列オブジェクトがstr型であるかどうかを判別します。str型ではなくユニコード型である場合は、uft8を使用してstr型にエンコードします。
# coding: utf-8
from pprint import PrettyPrinter
# 继承 PrettyPrinter,复写 format 方法
class MyPrettyPrinter(PrettyPrinter):
def format(self, object, context, maxlevels, level):
if isinstance(object, unicode):
return (object.encode('utf8'), True, False)
return PrettyPrinter.format(self, object, context, maxlevels, level)
info = [{"id":1580615,"name":u"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]
MyPrettyPrinter().pprint(info)
出力は次のとおりです。中国語の表示の問題は解決されました。
二重引用符を印刷する
中国の問題を解決した後、pprintを二重引用符で印刷する方法を見てみましょう。
PrettyPrinterオブジェクトをインスタンス化すると、コンテンツを出力する場所を示すストリームオブジェクトを受け取ることができます。デフォルトでは、標準出力であるストリームsys.stdoutが使用されます。
次に、出力コンテンツを変更する必要があります。つまり、出力の一重引用符を二重引用符に置き換えます。
次に、ストリームタイプオブジェクトを自分で定義できます。writeメソッドを実装している限り、オブジェクトは親クラスを継承する必要はありません。
アイデアがあれば、次のようにコードを書き始めることができます。
# coding: utf-8
from pprint import PrettyPrinter
class MyPrettyPrinter(PrettyPrinter):
def format(self, object, context, maxlevels, level):
if isinstance(object, unicode):
return (object.encode('utf8'), True, False)
return PrettyPrinter.format(self, object, context, maxlevels, level)
class MyStream():
def write(self, text):
print text.replace('\'', '"')
info = [{"id":1580615,"name":u"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]
MyPrettyPrinter(stream=MyStream()).pprint(info)
私はそれを実行しようとしました、私の神、それはこのようにどうですか。
[
{
"des"
:
2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青
,
"downloadUrl":
"app/com.renren.mobile.android/com.renren.mobile.android.apk"
,
"iconUrl":
"app/com.renren.mobile.android/icon.jpg"
,
"id":
1580615
,
"name":
皮的嘛
,
"packageName":
"com.renren.mobile.android"
,
"size":
21803987
,
"stars":
2
}
,
{
"des"
:
斗鱼271934走过路过不要错过,这里有最好的鸡儿
,
"downloadUrl":
"app/com.ct.client/com.ct.client.apk"
,
"iconUrl":
"app/com.ct.client/icon.jpg"
,
"id":
1540629
,
"name":
不存在的
,
"packageName":
"com.ct.client"
,
"size":
4794202
,
"stars":
2
}
]
いくつかの調査の結果、コンテンツはデフォルトで印刷機能を使用して改行を追加するため、そのことを知りました。
では、print関数で印刷されたコンテンツを折り返さないようにするにはどうすればよいでしょうか。
方法は簡単ですが、多くの人は知らないでしょう。行のコンマの後に印刷コンテンツを追加するだけです。
次のように。
問題を理解してから、コードを変更します
# coding: utf-8
from pprint import PrettyPrinter
class MyPrettyPrinter(PrettyPrinter):
def format(self, object, context, maxlevels, level):
if isinstance(object, unicode):
return (object.encode('utf8'), True, False)
return PrettyPrinter.format(self, object, context, maxlevels, level)
class MyStream():
def write(self, text):
print text.replace('\'', '"'),
info = [{"id":1580615,"name":u"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":u"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":u"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":u"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]
MyPrettyPrinter(stream=MyStream()).pprint(info)
ついに成功しました、それは簡単ではありませんでした。
3.なぜわざわざ
上記を投げることで、私はついに私の需要の夢を実現しました。
その代償は、私がそれを達成するのに2時間かかったということです。シャオバイにとって、彼はそのようなことをする自信と忍耐力を持っていないかもしれません。
つまり、私が言いたいのは、Python 2でのpprintは、実際にはもう使用しないということです。
明らかに良い選択肢があり、寿命が短いので、なぜ私はそれを言う必要があります。Pythonが使用されているので、もちろんそれがどれほど単純で、どのようにそれを行うのか、なぜ気になりますか?1行のコードで問題を解決できますが、2つ書く必要がありますクラス、それはトラブルを求めていませんか?(私は自分を叱っていますか?
pprintを放棄する場合は、json.dumpsを使用することをお勧めします。pprintを二度と使用したくないことをお約束します。
中国語を印刷
実際、中国語を印刷できないことはPython 2によって引き起こされる大きな落とし穴であり、pprintを完全に非難することはできません。
しかし、同じ問題については、json.dumpsで、パラメーターを追加するだけです。これは、pprintよりもそれほど単純ではありません。
具体的なコード例は次のとおりです。
>>> info = [{"id":1580615,"name":"皮的嘛","packageName":"com.renren.mobile.android","iconUrl":"app/com.renren.mobile.android/icon.jpg","stars":2,"size":21803987,"downloadUrl":"app/com.renren.mobile.android/com.renren.mobile.android.apk","des":"2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青"},{"id":1540629,"name":"不存在的","packageName":"com.ct.client","iconUrl":"app/com.ct.client/icon.jpg","stars":2,"size":4794202,"downloadUrl":"app/com.ct.client/com.ct.client.apk","des":"斗鱼271934走过路过不要错过,这里有最好的鸡儿"}]
>>>
>>> import json
>>>
>>>
>>> print json.dumps(info, indent=4, ensure_ascii=False)
[
{
"downloadUrl": "app/com.renren.mobile.android/com.renren.mobile.android.apk",
"iconUrl": "app/com.renren.mobile.android/icon.jpg",
"name": "皮的嘛",
"stars": 2,
"packageName": "com.renren.mobile.android",
"des": "2011-2017你的铁头娃一直在这儿。中国最大的实名制SNS网络平台,嫩头青",
"id": 1580615,
"size": 21803987
},
{
"downloadUrl": "app/com.ct.client/com.ct.client.apk",
"iconUrl": "app/com.ct.client/icon.jpg",
"name": "不存在的",
"stars": 2,
"packageName": "com.ct.client",
"des": "斗鱼271934走过路过不要错过,这里有最好的鸡儿",
"id": 1540629,
"size": 4794202
}
]
>>>
json.dumpsには2つの重要なパラメータがあります。
- indent = 4:ユニットを4つのスペースでインデントします
- sure_ascii = False:中国語を使用できるように、ASCIIでエンコードされていない文字を受け入れます
pprintと比較すると、json.dumpsは勝利であると言えます。
- 2つのパラメーターですべてのニーズを満たすことができます(中国語と二重引用符を印刷)
- Python 2でも、中国語を使用する場合、
u'中文'
このようなアプローチを使用する必要はありません。 - Python2とPython3はまったく同じ方法で記述されているため、この点で互換性の問題を考慮する必要はありません。
4.まとめ
もともと非常に単純な観点から、pprintがこれら2つの要件を達成するのがどれほど難しいかを証明するために、pprintのソースコードの研究に多くの時間を費やしました(さまざまな処理は実際には非常に複雑です)が、幸いなことに、最終的には実行できます。褒賞。
この記事の共有はここにあります、この記事を読んで、私はあなたが3つの知識ポイントを得ることができると思います
- コアポイント:Python2ではpprintを使用しないでください
- 本当にそれを使用したいが、同じ変換要件がある場合は、私の実装を参照できます
- Python2のprintステートメントの後にコンマを追加できます
上記。この記事がお役に立てば幸いです。多数(300)のイラストが含まれているオリジナルの「PyCharmChinese Guide」e-bookをお勧めします。これはよくできていて、すべてのPythonエンジニアによるコレクションに値します。
アドレスは次のとおりです:http://pycharm.iswbm.com