[解決済み】JSONからUnicodeの代わりに文字列オブジェクトを取得する方法は?
質問
を使っています。 Python 2 からのJSONをパースするために ASCIIエンコード テキストファイルです。
これらのファイルを
json
または
simplejson
の場合、すべての文字列値は文字列オブジェクトではなく、Unicodeオブジェクトにキャストされます。問題は、文字列オブジェクトしか受け付けないいくつかのライブラリでデータを使用しなければならないことです。I
ライブラリは変更できない
また、更新もできません。
Unicodeではなく、文字列のオブジェクトを取得することは可能でしょうか?
例
>>> import json
>>> original_list = ['a', 'b']
>>> json_list = json.dumps(original_list)
>>> json_list
'["a", "b"]'
>>> new_list = json.loads(json_list)
>>> new_list
[u'a', u'b'] # I want these to be of type `str`, not `unicode`
更新情報
この質問は だいぶ前 に行き詰まった時、「このままではいけない。 Python 2 . 今日の簡単できれいな解決策の一つは、最近のバージョンのPythonを使うことです - すなわち パイソン3 と進む。
どのように解決するのですか?
による解決策
object_hook
[編集]: Python 2.7用に更新 と 3.xとの互換性。
import json
def json_load_byteified(file_handle):
return _byteify(
json.load(file_handle, object_hook=_byteify),
ignore_dicts=True
)
def json_loads_byteified(json_text):
return _byteify(
json.loads(json_text, object_hook=_byteify),
ignore_dicts=True
)
def _byteify(data, ignore_dicts = False):
if isinstance(data, str):
return data
# if this is a list of values, return list of byteified values
if isinstance(data, list):
return [ _byteify(item, ignore_dicts=True) for item in data ]
# if this is a dictionary, return dictionary of byteified keys and values
# but only if we haven't already byteified it
if isinstance(data, dict) and not ignore_dicts:
return {
_byteify(key, ignore_dicts=True): _byteify(value, ignore_dicts=True)
for key, value in data.items() # changed to .items() for python 2.7/3
}
# python 3 compatible duck-typing
# if this is a unicode string, return its string representation
if str(type(data)) == "<type 'unicode'>":
return data.encode('utf-8')
# if it's anything else, return it in its original form
return data
使用例です。
>>> json_loads_byteified('{"Hello": "World"}')
{'Hello': 'World'}
>>> json_loads_byteified('"I am a top-level string"')
'I am a top-level string'
>>> json_loads_byteified('7')
7
>>> json_loads_byteified('["I am inside a list"]')
['I am inside a list']
>>> json_loads_byteified('[[[[[[[["I am inside a big nest of lists"]]]]]]]]')
[[[[[[[['I am inside a big nest of lists']]]]]]]]
>>> json_loads_byteified('{"foo": "bar", "things": [7, {"qux": "baz", "moo": {"cow": ["milk"]}}]}')
{'things': [7, {'qux': 'baz', 'moo': {'cow': ['milk']}}], 'foo': 'bar'}
>>> json_load_byteified(open('somefile.json'))
{'more json': 'from a file'}
この仕組みと、なぜ使うのか?
マーク・エイメリーの機能 は、これらよりも短くてわかりやすいので、何が言いたいのか?なぜ、それらを使いたいのですか?
純粋に パフォーマンス . Markの回答は、まずJSONテキストをunicode文字列で完全にデコードし、次にデコードされた値全体を再帰してすべての文字列をバイト文字列に変換しています。これには、いくつかの望ましくない効果があります。
- デコードされた構造体全体のコピーがメモリ上に作成されます。
- もし、JSONオブジェクトが 本当に 深いネスト(500レベル以上)になると、Pythonの最大再帰深度にぶつかります。
この回答では、これらのパフォーマンスの問題を緩和するために
object_hook
のパラメータは
json.load
と
json.loads
. から
ドキュメント
:
object_hook
はオプションの関数で、オブジェクトリテラルをデコードした結果で呼び出されます。dict
). object_hook の返り値がdict
. この機能は、カスタムデコーダの実装に使用できます。
他の辞書の何階層もネストした辞書は
object_hook
デコードされると
そのため、この時点で内部の文字列やリストをバイト化し、後で深い再帰処理を行う必要をなくすことができます。
マークの回答は
object_hook
このままでは、ネストした辞書に再帰してしまうからです。この回答では、再帰を防ぐために
ignore_dicts
パラメータを
_byteify
常に渡される
ただし
いつ
object_hook
を渡すと、新しい
dict
をバイト化する。その
ignore_dicts
フラグは
_byteify
を無視するために
dict
は既にバイト化されているので
最後に、私たちが実装している
json_load_byteified
と
json_loads_byteified
コール
_byteify
と
ignore_dicts=True
から返された結果に対して
json.load
または
json.loads
を使うことで、デコードされるJSONテキストに
dict
をトップレベルにしています。
関連
-
Pythonコンテナのための組み込み汎用関数操作
-
[解決済み] Pythonで現在時刻を取得する方法
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] Pythonで文字列の部分文字列を取得するにはどうすればよいですか?
-
[解決済み] Microsoft JSONの日付はどのようにフォーマットするのですか?
-
[解決済み] なぜlist.join(string)ではなくstring.join(list)なのでしょうか?
-
[解決済み] JSONファイルをprettyprintする方法は?
-
[解決済み] .NETでC#オブジェクトをJSON文字列に変換するには?
-
[解決済み] クラスをJSONシリアライザブルにする方法
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python カメの描画コマンドとその例
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み】Pythonスクリプトで「Expected 2D array, got 1D array instead: 」というエラーが発生?
-
[解決済み】TypeError: re.findall()でバイトのようなオブジェクトに文字列パターンを使用することはできません。)
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】Python elifの構文が無効です【終了しました
-
[解決済み】Python - "ValueError: not enough values to unpack (expected 2, got 1)" の修正方法 [閉店].
-
[解決済み】django インポートエラー - core.managementという名前のモジュールがない
-
[解決済み】リストの文字列表現をリストに変換する方法は?
-
[解決済み] Python: json.loads は 'u' を前置詞とするアイテムを返す