python loads - json.dumps에 utf-8 텍스트를 UTF8로 저장하고 이스케이프 시퀀스로 저장하지 않습니다.




to unicode (8)

샘플 코드 :

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

문제는 사람이 읽을 수있는 것이 아닙니다. 내 (똑똑한) 사용자는 JSON 덤프로 텍스트 파일을 확인하거나 편집하려고합니다. (그리고 나는 XML을 사용하지 않을 것입니다)

\ uXXXX 대신 utf-8 json 문자열로 객체를 직렬화하는 방법이 있습니까?

이 도움이되지 않습니다 :

>>> output = json_string.decode('string-escape')
"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"

작품은,하지만 어떤 하위 개체는 파이썬 유니 코드 및 utf - 8 아니라면 쓰레기를 버릴거야 :

>>> #### ok:
>>> s= json.dumps( "ברי צקלה", ensure_ascii=False)    
>>> print json.loads(s)   
ברי צקלה

>>> #### NOT ok:
>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }
>>> print d
{1: '\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94', 
 2: u'\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94'}
>>> s = json.dumps( d, ensure_ascii=False, encoding='utf8')
>>> print json.loads(s)['1']
ברי צקלה
>>> print json.loads(s)['2']
××¨× ×¦×§××

Answers

업데이트 : 이것은 잘못된 대답이지만 잘못된 이유를 이해하는 것은 여전히 ​​유용합니다. 의견보기.

unicode-escape 어떻습니까?

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

다음은 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]

다음은 내 이해 var 읽기 위와 구글입니다.

# 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://.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://.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'
"""

가능한 경우 코덱을 사용하십시오.

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

케이크처럼 쉽다.

파일에 쓰려면

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)

stdin으로 인쇄하려면

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

json.dumps() ensure_ascii=False 스위치를 사용하고 값을 수동으로 UTF-8로 인코딩합니다.

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

이 파일을 파일에 쓰는 경우 open() io.open() 대신 io.open() 사용하여 작성할 때 유니 코드 값을 인코딩하는 파일 객체를 생성 한 다음 json.dump() 를 사용하여 해당 파일에 쓸 수 있습니다 :

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

Python 3에서 내장 open()io.open() 의 별칭입니다. ensure_ascii=False 플래그가 unicodestr 객체의 혼합 을 생성 할 수 있는 json 모듈에 버그 가 있음을 유의하십시오. 파이썬 2의 해결 방법은 다음과 같습니다.

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))

UTF-8로 인코딩 된 바이트 문자열 (Python 2의 str 형식, Python 3의 bytes 형식)을 전달하는 경우 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']
ברי צקלה

두 번째 샘플은 유효한 유니 코드가 아닙니다 . 유니 코드 리터럴로 UTF-8 바이트를 주면 결코 작동 하지 않을 것입니다.

>>> s = u'\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94'
>>> print s
××¨× ×¦×§××
>>> print s.encode('latin1').decode('utf8')
ברי צקלה

해당 문자열을 라틴어 1 (유니 코드 코드 포인트가 일대일 바이트로 매핑)로 인코딩 한 다음 UTF-8로 디코딩하면 예상 출력이 표시됩니다. JSON과 관련이 없으며 잘못된 입력을 사용하는 것과 관련이 있습니다. 결과는 Mojibake )라고합니다.

문자열 리터럴에서 유니 코드 값을 얻은 경우 잘못된 코덱을 사용하여 디코딩되었습니다. 터미널이 잘못 구성되었거나 텍스트 편집기가 파이썬에 파일을 읽으 려했던 것과 다른 코덱을 사용하여 소스 코드를 저장 한 것일 수 있습니다. 또는 잘못된 코덱을 적용한 라이브러리에서 가져온 것입니다. 이 모든 것은 JSON 라이브러리와 아무 관련이 없습니다 .


json.dumps에서 ensure_ascii = False를 사용하면 Martijn이 지적한대로이 문제를 해결할 수있는 올바른 방향입니다. 그러나 이로 인해 예외가 발생할 수 있습니다.

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

site.py 또는 sitecustomize.py에서 sys.getdefaultencoding ()을 올바르게 설정하려면 추가 설정이 필요합니다. site.py는 lib / python2.7 /에 있으며 sitecustomize.py는 lib / python2.7 / site-packages에 있습니다.

defsetencoding ()에서 site.py를 사용하려면 : 0 : 1 인 경우 첫 번째를 1 : 1로 변경하여 파이썬이 운영 체제의 로켈을 사용하도록합니다.

sitecustomize.py를 선호한다면, 만들지 않은 경우 존재하지 않을 수도 있습니다. 단순히 다음 줄을 넣으십시오.

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

다음과 같이 utf-8 형식의 중국어 json 출력을 수행 할 수 있습니다.

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

\ n 이스케이프 된 json 문자열 대신 utf-8로 인코딩 된 문자열을 얻습니다.

기본 인코딩을 확인하려면 다음 단계를 따르세요.

print sys.getdefaultencoding()

site.py 또는 sitecustomize.py 설정을 확인하려면 "utf-8"또는 "UTF-8"이 있어야합니다.

대화 형 Python 콘솔에서는 sys.setdefaultencoding ( "utf-8")을 할 수 없다는 점에 유의하십시오.


좀 더 간결한 것은 :

for i in my_list:
    # got a list
if not my_list:
    # not a list

루프에서 목록의 길이를 변경하지 않는다고 가정합니다.

Oli에서 편집 : 메모리 사용에 대한 내 걱정을 보완하기 위해 다음 with 원할 것입니다.

with get_list() as my_list:
    for i in my_list:
        # got a list
    if not my_list:
        # not a list

그러나 그렇습니다, 그것은 문제를 둘러싼 아주 간단한 방법입니다.





python json unicode utf-8 escaping