Utf-8 पाठ को json.dumps में UTF8 के रूप में सहेजना, \ u एस्केप अनुक्रम के रूप में नहीं


472

नमूना कोड:

>>> import json
>>> json_string = json.dumps("ברי צקלה")
>>> print json_string
"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"

समस्या: यह मानव पठनीय नहीं है। मेरे (स्मार्ट) उपयोगकर्ता JSON डंप के साथ पाठ फ़ाइलों को सत्यापित या संपादित करना चाहते हैं (और मैं XML का उपयोग नहीं करूँगा)।

क्या UTF-8 JSON स्ट्रिंग्स (इसके बजाय \uXXXX) में वस्तुओं को अनुक्रमित करने का एक तरीका है ?


9
+ )רי לקלה :) के लिए))
rubmz

जवाबों:


640

ensure_ascii=Falseस्विच का उपयोग करें json.dumps(), फिर मान को UTF-8 में मैन्युअल रूप से एन्कोड करें:

>>> json_string = json.dumps("ברי צקלה", ensure_ascii=False).encode('utf8')
>>> json_string
b'"\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94"'
>>> print(json_string.decode())
"ברי צקלה"

यदि आप किसी फ़ाइल को लिख रहे हैं, json.dump()तो उसका उपयोग करें और उसे एनकोड करने के लिए फ़ाइल ऑब्जेक्ट पर छोड़ दें:

with open('filename', 'w', encoding='utf8') as json_file:
    json.dump("ברי צקלה", json_file, ensure_ascii=False)

पायथन 2 के लिए कैवेट

पायथन 2 के लिए, खाते में लेने के लिए कुछ और चेतावनी हैं। यदि आप इसे किसी फ़ाइल में लिख रहे हैं, तो आप एक फ़ाइल ऑब्जेक्ट का निर्माण करने के io.open()बजाय इसका उपयोग कर सकते हैं open()जो आपके लिखते समय यूनिकोड मानों को एनकोड करता है, फिर json.dump()उस फ़ाइल पर लिखने के बजाय इसका उपयोग करें :

with io.open('filename', 'w', encoding='utf8') as json_file:
    json.dump(u"ברי צקלה", json_file, ensure_ascii=False)

ध्यान दें कि मॉड्यूल मेंjson एक बग है जहां ensure_ascii=Falseझंडा और वस्तुओं के मिश्रण का उत्पादन कर सकता है । पायथन 2 के लिए समाधान तब है:unicodestr

with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(u"ברי צקלה", ensure_ascii=False)
    # unicode(data) auto-decodes data to unicode if str
    json_file.write(unicode(data))

पायथन 2 में, बाइट स्ट्रिंग्स (प्रकार str) का उपयोग करते समय , UTF-8 को एन्कोड किया गया, यह भी सुनिश्चित करें कि encodingकीवर्ड सेट करें :

>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }
>>> d
{1: '\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94', 2: u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'}

>>> s=json.dumps(d, ensure_ascii=False, encoding='utf8')
>>> s
u'{"1": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4", "2": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"}'
>>> json.loads(s)['1']
u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'
>>> json.loads(s)['2']
u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'
>>> print json.loads(s)['1']
ברי צקלה
>>> print json.loads(s)['2']
ברי צקלה

72

किसी फ़ाइल में लिखने के लिए

import codecs
import json

with codecs.open('your_file.txt', 'w', encoding='utf-8') as f:
    json.dump({"message":"xin chào việt nam"}, f, ensure_ascii=False)

स्टडआउट करने के लिए मुद्रित करने के लिए

import json
print(json.dumps({"message":"xin chào việt nam"}, ensure_ascii=False))

1
SyntaxError: गैर- ASCII वर्ण '\ xc3' फ़ाइल json-utf8.py पर पंक्ति 5 पर, लेकिन कोई एन्कोडिंग घोषित नहीं किया गया; देख python.org/dev/peps/pep-0263 जानकारी के लिए
एलेक्स

धन्यवाद! मुझे नहीं पता था कि यह इतना आसान था। आपको केवल सावधान रहने की आवश्यकता है यदि आप जिस डेटा को जसन में परिवर्तित कर रहे हैं वह अविश्वासित उपयोगकर्ता इनपुट है।
करीम सोनबोल

@ एलेक्स ने आपको बताया कि उस मुद्दे से कैसे बचा जाए?
गैब्रियल फेयर

@ गैब्रिएल स्पष्ट रूप से, मुझे याद नहीं है। स्निपेट को एक तरफ रखना कुछ इतना महत्वपूर्ण नहीं था :(
एलेक्स

केवल codecsपुस्तकालय का उपयोग करके मेरे लिए काम किया । धन्यवाद!
igorkf

29

अद्यतन: यह गलत उत्तर है, लेकिन यह समझना अभी भी उपयोगी है कि यह गलत क्यों है। टिप्पणी देखो।

कैसे के बारे में unicode-escape?

>>> d = {1: "ברי צקלה", 2: u"ברי צקלה"}
>>> json_str = json.dumps(d).decode('unicode-escape').encode('utf8')
>>> print json_str
{"1": "ברי צקלה", "2": "ברי צקלה"}

9
unicode-escapeआवश्यक नहीं है: आप json.dumps(d, ensure_ascii=False).encode('utf8')इसके बजाय उपयोग कर सकते हैं । और यह गारंटी नहीं दी जाती है कि json बिल्कुल समान नियमों का उपयोग unicode-escapeपायथन में कोडर के रूप में करता है सभी मामलों में, परिणाम हो सकता है या कुछ कोने के मामले में समान नहीं हो सकता है। डाउनवोट एक अनावश्यक और संभवतः गलत रूपांतरण के लिए है। असंबंधित: print json_strकेवल utf8 स्थानों के लिए काम करता है या अगर PYTHONIOENCODINGenvvar यहां utf8 निर्दिष्ट करता है (इसके बजाय यूनिकोड प्रिंट करें)।
JFS

3
एक और मुद्दा: स्ट्रिंग मानों में कोई भी डबल उद्धरण उनके भागने को खो देगा, इसलिए इसका परिणाम JSON आउटपुट टूटेगा
मार्टिन पीटर्स

पाइथन 3 में त्रुटि: विशेषता: 'str' ऑब्जेक्ट में कोई विशेषता 'डिकोड' नहीं है
Gank

1
यूनिकोड-एस्केप ठीक काम करता है! मैं इस उत्तर को सही मानूंगा।
कार्यकर्ता

@jfs नहीं, json.dumps(d, ensure_ascii=False).encode('utf8')कम से कम मेरे लिए काम नहीं कर रहा है। मैं हो रहा हूँ UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position ...-रोर। unicode-escapeसंस्करण ठीक लेकिन काम करता है।
turingtested

24

पीटर्स के अजगर 2 बढ़त के मामले में विफल रहता है:

d = {u'keyword': u'bad credit  \xe7redit cards'}
with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(d, ensure_ascii=False).decode('utf8')
    try:
        json_file.write(data)
    except TypeError:
        # Decode data to Unicode first
        json_file.write(data.decode('utf8'))

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 25: ordinal not in range(128)

यह .decode ('utf8') लाइन के भाग 3 पर दुर्घटनाग्रस्त हो गया था। मैंने उस कदम से बचने के साथ-साथ एससीआई के विशेष आवरण से प्रोग्राम को बहुत सरल बनाकर समस्या को ठीक किया:

with io.open('filename', 'w', encoding='utf8') as json_file:
  data = json.dumps(d, ensure_ascii=False, encoding='utf8')
  json_file.write(unicode(data))

cat filename
{"keyword": "bad credit  çredit cards"}

2
'किनारे का मामला' मेरी ओर से केवल एक मूर्खतापूर्ण त्रुटि थी। unicode(data)अपवाद से निपटने के बजाय आपका दृष्टिकोण बेहतर विकल्प है। ध्यान दें कि encoding='utf8'कीवर्ड तर्क का उत्पादन करने वाले उत्पादन से कोई लेना-देना नहीं है json.dumps(); यह फ़ंक्शन प्राप्त करने वाले strइनपुट को डिकोड करने के लिए उपयोग किया जाता है ।
मार्टिन पीटर्स

2
@MartijnPieters: या सरल: open('filename', 'wb').write(json.dumps(d, ensure_ascii=False).encode('utf8'))यह काम करता है कि dumpsरिटर्न (ascii-only) str या यूनिकोड ऑब्जेक्ट।
जफ

@JFSebastian: सही है, क्योंकि पहले अनुमानित रूप से str.encode('utf8') डिकोड होते हैं । लेकिन ऐसा होता है unicode(data), अगर कोई strवस्तु दी जाती है । :-) io.open()हालांकि, आपको अधिक विकल्प देता है, जिसमें एक कोडेक का उपयोग करना शामिल है जो BOM लिखता है और आप JSON डेटा का अनुसरण किसी और चीज़ से कर रहे हैं।
मार्टिन पीटर्स

@MartijnPieters: पायदान .encode('utf8')2 और 3 (एक ही कोड) पर आधारित संस्करण काम करता है। unicodeपाइथन 3 पर कोई भी नहीं है। असंबंधित: json फ़ाइलों को BOM का उपयोग नहीं करना चाहिए (हालाँकि एक पुष्टि करने वाला json पार्सर BOM को अनदेखा कर सकता है, त्रुटिपूर्ण 3983 देखें )।
JFS

समस्या encoding='utf8'को json.dumpsहल करने के लिए जोड़ना । PS मेरे पास डंप करने के लिए एक सिरिलिक पाठ है
मैक्स एल

8

अजगर 3.7 के रूप में निम्नलिखित कोड ठीक काम करता है:

from json import dumps
result = {"symbol": "ƒ"}
json_string = dumps(result, sort_keys=True, indent=2, ensure_ascii=False)
print(json_string)

आउटपुट:

{"symbol": "ƒ"}

2
अजगर 3.6 में भी (सिर्फ सत्यापित)।
बेरी त्सकाला

7

ऊपर और Google पर मेरी समझ का वर्जन उत्तर है।

# coding:utf-8
r"""
@update: 2017-01-09 14:44:39
@explain: str, unicode, bytes in python2to3
    #python2 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 7: ordinal not in range(128)
    #1.reload
    #importlib,sys
    #importlib.reload(sys)
    #sys.setdefaultencoding('utf-8') #python3 don't have this attribute.
    #not suggest even in python2 #see:http://stackoverflow.com/questions/3828723/why-should-we-not-use-sys-setdefaultencodingutf-8-in-a-py-script
    #2.overwrite /usr/lib/python2.7/sitecustomize.py or (sitecustomize.py and PYTHONPATH=".:$PYTHONPATH" python)
    #too complex
    #3.control by your own (best)
    #==> all string must be unicode like python3 (u'xx'|b'xx'.encode('utf-8')) (unicode 's disappeared in python3)
    #see: http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

    #how to Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence
    #http://stackoverflow.com/questions/18337407/saving-utf-8-texts-in-json-dumps-as-utf8-not-as-u-escape-sequence
"""

from __future__ import print_function
import json

a = {"b": u"中文"}  # add u for python2 compatibility
print('%r' % a)
print('%r' % json.dumps(a))
print('%r' % (json.dumps(a).encode('utf8')))
a = {"b": u"中文"}
print('%r' % json.dumps(a, ensure_ascii=False))
print('%r' % (json.dumps(a, ensure_ascii=False).encode('utf8')))
# print(a.encode('utf8')) #AttributeError: 'dict' object has no attribute 'encode'
print('')

# python2:bytes=str; python3:bytes
b = a['b'].encode('utf-8')
print('%r' % b)
print('%r' % b.decode("utf-8"))
print('')

# python2:unicode; python3:str=unicode
c = b.decode('utf-8')
print('%r' % c)
print('%r' % c.encode('utf-8'))
"""
#python2
{'b': u'\u4e2d\u6587'}
'{"b": "\\u4e2d\\u6587"}'
'{"b": "\\u4e2d\\u6587"}'
u'{"b": "\u4e2d\u6587"}'
'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

'\xe4\xb8\xad\xe6\x96\x87'
u'\u4e2d\u6587'

u'\u4e2d\u6587'
'\xe4\xb8\xad\xe6\x96\x87'

#python3
{'b': '中文'}
'{"b": "\\u4e2d\\u6587"}'
b'{"b": "\\u4e2d\\u6587"}'
'{"b": "中文"}'
b'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

b'\xe4\xb8\xad\xe6\x96\x87'
'中文'

'中文'
b'\xe4\xb8\xad\xe6\x96\x87'
"""

5

यहाँ json.dump () का उपयोग करके मेरा समाधान दिया गया है:

def jsonWrite(p, pyobj, ensure_ascii=False, encoding=SYSTEM_ENCODING, **kwargs):
    with codecs.open(p, 'wb', 'utf_8') as fileobj:
        json.dump(pyobj, fileobj, ensure_ascii=ensure_ascii,encoding=encoding, **kwargs)

जहाँ SYSTEM_ENCODING सेट है:

locale.setlocale(locale.LC_ALL, '')
SYSTEM_ENCODING = locale.getlocale()[1]

4

यदि संभव हो तो कोडेक्स का उपयोग करें,

with codecs.open('file_path', 'a+', 'utf-8') as fp:
    fp.write(json.dumps(res, ensure_ascii=False))

1

यहां मूल उत्तर के लिए धन्यवाद। अजगर 3 के साथ कोड की निम्नलिखित पंक्ति:

print(json.dumps(result_dict,ensure_ascii=False))

ठीक था। यदि यह अनिवार्य नहीं है तो कोड में बहुत अधिक टेक्स्ट न लिखने की कोशिश करने पर विचार करें।

यह अजगर सांत्वना के लिए काफी अच्छा हो सकता है। हालांकि, एक सर्वर को संतुष्ट करने के लिए आपको यहां बताए अनुसार लोकल सेट करने की आवश्यकता हो सकती है (यदि यह अपाचे 2 पर है) http://blog.dscpl.com.au/2014/09/setting-lang-and-lcall-when-use .html

मूल रूप से ubuntu पर जो भी भाषा या लोकल इंस्‍टॉल होती है, उसे इंस्‍टॉल करें

locale -a 

इसे स्थापित करें जहां XX आपकी भाषा है

sudo apt-get install language-pack-XX

उदाहरण के लिए:

sudo apt-get install language-pack-he

निम्नलिखित पाठ को / etc / apache2 / envvrs में जोड़ें

export LANG='he_IL.UTF-8'
export LC_ALL='he_IL.UTF-8'

आपको उम्मीद है कि आप अपाचे से अजगर त्रुटियों को प्राप्त नहीं करेंगे जैसे:

प्रिंट (js) यूनिकोडएकोडकोड: 'एससीआईआई' कोडक पात्रों को 41-45 की स्थिति में सांकेतिक शब्दों में बदलना नहीं कर सकता: क्रम में नहीं (128)

अपाचे में भी डिफ़ॉल्ट एन्कोडिंग बनाने की कोशिश करें जैसा कि यहाँ बताया गया है:
अपाचे के लिए डिफ़ॉल्ट एन्कोडिंग को UTF-8 में कैसे बदलें?

इसे जल्दी करें क्योंकि अपाचे त्रुटियां डिबग के लिए दर्द हो सकती हैं और आप गलती से यह सोच सकते हैं कि यह अजगर से है जो संभवतः उस स्थिति में नहीं है


1

यदि आप JSON स्ट्रिंग को किसी फ़ाइल और फ़ाइल सामग्री अरबी पाठ से लोड कर रहे हैं। तब यह काम करेगा।

फ़ाइल मान लें: arabic.json

{ 
"key1" : "لمستخدمين",
"key2" : "إضافة مستخدم"
}

अरेबिक.जेसन फ़ाइल से अरबी सामग्री प्राप्त करें

with open(arabic.json, encoding='utf-8') as f:
   # deserialises it
   json_data = json.load(f)
   f.close()


# json formatted string
json_data2 = json.dumps(json_data, ensure_ascii = False)

Django टेम्प्लेट में JSON डेटा का उपयोग करने के लिए निम्न चरणों का पालन करें:

# If have to get the JSON index in Django Template file, then simply decode the encoded string.

json.JSONDecoder().decode(json_data2)

किया हुआ! अब हम अरबी मूल्य के साथ JSON इंडेक्स के रूप में परिणाम प्राप्त कर सकते हैं।


fh.close() fhअपरिभाषित है।
AMC

अब यह ठीक हो गया है। यह होगाf.close()
चंदन शर्मा

0

समस्या को हल करने के लिए यूनिकोड-एस्केप का उपयोग करें

>>>import json
>>>json_string = json.dumps("ברי צקלה")
>>>json_string.encode('ascii').decode('unicode-escape')
'"ברי צקלה"'

समझाना

>>>s = '漢  χαν  хан'
>>>print('unicode: ' + s.encode('unicode-escape').decode('utf-8'))
unicode: \u6f22  \u03c7\u03b1\u03bd  \u0445\u0430\u043d

>>>u = s.encode('unicode-escape').decode('utf-8')
>>>print('original: ' + u.encode("utf-8").decode('unicode-escape'))
original:   χαν  хан

मूल संसाधन chu https://blog.csdn.net/chuatony/article/details/72628868


-3

मार्टिज्न द्वारा बताया गया है कि इस समस्या को हल करने के लिए सही दिशा है। हालांकि, यह एक अपवाद बढ़ा सकता है:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 1: ordinal not in range(128)

आपको अपने sys.getdefaultencoding () को सही सेट करने के लिए या तो साइट-थ्रू या साइटकस्टमइंज़ोम में अतिरिक्त सेटिंग्स की आवश्यकता है। site.py lib / python2.7 / के अंतर्गत है और sitecustomize.py lib / python2.7 / site-package के अंतर्गत है।

यदि आप def setencoding () के तहत साइट थिंकपैड का उपयोग करना चाहते हैं (तो: 0: to if 1: सबसे पहले बदलें, ताकि अजगर आपके ऑपरेशन सिस्टम के लोकेल का उपयोग करेगा।

यदि आप sitecustomize.py का उपयोग करना पसंद करते हैं, जो आपके द्वारा निर्मित न होने पर मौजूद नहीं हो सकता है। बस इन पंक्तियों को रखें:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

फिर आप utf-8 प्रारूप में कुछ चीनी जोंस आउटपुट कर सकते हैं, जैसे:

name = {"last_name": u"王"}
json.dumps(name, ensure_ascii=False)

आपको एक यूएफ-बचा ​​हुआ जस स्ट्रिंग के बजाय एक utf-8 एन्कोडेड स्ट्रिंग मिलेगा।

अपने डिफ़ॉल्ट एन्कोडिंग को सत्यापित करने के लिए:

print sys.getdefaultencoding()

आपको अपनी साइट थिंकपैड या sitecustomize.py सेटिंग्स को सत्यापित करने के लिए "utf-8" या "UTF-8" मिलना चाहिए।

कृपया ध्यान दें कि आप इंटरैक्टिव पायथन कंसोल पर sys.setdefaultencoding ("utf-8") नहीं कर सकते थे।


2
नहीं। यह मत करो। डिफ़ॉल्ट वर्ण एन्कोडिंग में संशोधन के साथ कोई संबंध नहीं है jsonकी ensure_ascii=False। यदि आप अन्यथा सोचते हैं तो एक न्यूनतम पूर्ण कोड उदाहरण प्रदान करें।
jfs

आपको यह अपवाद तभी मिलता है जब आप या तो गैर-एएससीआईआई बाइट स्ट्रिंग्स (जैसे यूनिकोड मान नहीं) में फ़ीड करते हैं या गैर-एएससीआईआई बाइट स्ट्रिंग के साथ परिणामी JSON मान (एक यूनिकोड स्ट्रिंग) को संयोजित करने का प्रयास करते हैं। डिफ़ॉल्ट एन्कोडिंग को UTF-8 में सेट करना अनिवार्य रूप से एक अंतर्निहित समस्या का कारण है, आप अपने स्ट्रिंग डेटा को ठीक से प्रबंधित नहीं कर रहे हैं।
मार्टिन पीटर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.