ইউএসএফ 8 হিসাবে জসন.ডাম্পসে utf-8 পাঠ্য সংরক্ষণ করা, আপনার অব্যাহতি ক্রম হিসাবে নয়


472

কোডের উদাহরণ:

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

সমস্যা: এটি মানুষের পাঠযোগ্য নয়। আমার (স্মার্ট) ব্যবহারকারীরা জেএসএন ডাম্পের সাহায্যে পাঠ্য ফাইলগুলি যাচাই বা সম্পাদনা করতে চান (এবং আমি এক্সএমএল ব্যবহার না করবো)।

UTF-8 JSON স্ট্রিংগুলিতে (পরিবর্তে \uXXXX) অবজেক্টগুলিকে সিরিয়ালাইজ করার কোনও উপায় আছে কি ?


9
+ צקלה צקלה :) এর জন্য))
রুবমেজ

উত্তর:


639

এতে ensure_ascii=Falseস্যুইচটি ব্যবহার করুন json.dumps(), তারপরে মানটি নিজেই ইউটিএফ -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পতাকা একটি তৈরী করতে পারে মিশ্রণ এর unicodeএবং strবস্তু। পাইথন 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))

পাইথন 2-এ, strইউটিএফ -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)

Stdout প্রিন্ট করতে

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

1
সিনট্যাক্স এরিয়ার: নন-এএসসিআইআই অক্ষর '\ xc3' ফাইলটি লাইনে 5 লাইনে json-utf8.py, কিন্তু কোনও এনকোডিং ঘোষিত হয়নি; বিশদ জানতে পাইথন.আর.দেব / পেপস / পেপ ০২6363৩ দেখুন
অ্যালেক্স

ধন্যবাদ! আমি বুঝতে পারিনি যে এটি এত সহজ। আপনি যদি জসনকে রূপান্তর করছেন এমন ডেটা অবিশ্বস্ত ব্যবহারকারী ইনপুট হয় তবে আপনাকে কেবল সতর্ক হওয়া দরকার।
করিম সোনবোল

@ অ্যালেক্স আপনি কীভাবে এই সমস্যাটি এড়াবেন তা বুঝতে পেরেছেন?
গ্যাব্রিয়েল ফেয়ার

@ গ্যাব্রিয়েল খোলামেলাভাবে, আমার মনে নেই। স্নিপেটকে আলাদা করে রাখা এত গুরুত্বপূর্ণ কিছু ছিল না :(
অ্যালেক্স

কেবল 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')পরিবর্তে ব্যবহার করতে পারেন । এবং এটি কোনও গ্যারান্টিযুক্ত নয় যে জসন পাইথনে কোডেকের মতো একই নিয়মগুলি সমস্ত ক্ষেত্রেই ব্যবহার করে ie যেমন, কোনও কোনও কোণে ফলাফল একই বা নাও হতে পারে। ডাউনভোটটি একটি অপ্রয়োজনীয় এবং সম্ভবত ভুল রূপান্তরের জন্য। আনলেলেটেড: কেবলমাত্র ইউটিএফ 8 লোকেলের জন্য কাজ করে বা এনভ্বর যদি এখানে utf8 নির্দিষ্ট করে (পরিবর্তে ইউনিকোড প্রিন্ট করুন)। unicode-escapeprint json_strPYTHONIOENCODING
jfs

3
আরেকটি সমস্যা: স্ট্রিং মানগুলিতে যে কোনও ডাবল উদ্ধৃতি তাদের পলায়ন হারাবে, সুতরাং এর ফলে JSON আউটপুট ভাঙ্গা হবে ।
মার্টিজন পিটারস

পাইথন 3-তে ত্রুটি: অ্যাট্রিবিউটআরার: 'স্ট্র' অবজেক্টটির কোনও 'ডিকোড' নেই
গ্যাঙ্ক

1
ইউনিকোড-পলায়ন কাজ ভাল! আমি এই উত্তরটি সঠিক হিসাবে গ্রহণ করব।
কর্মী

@jfs না, json.dumps(d, ensure_ascii=False).encode('utf8')কমপক্ষে আমার জন্য কাজ করছে না। আমি UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position ...অস্থির হয়ে উঠছি unicode-escapeবৈকল্পিক জরিমানা তবে কাজ করে।
turestested

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)

এটি লাইন 3। ডিকোড ('utf8') অংশে ক্র্যাশ হচ্ছিল। আমি প্রোগ্রামটি আরও সহজ করে সেই পদক্ষেপটি এড়ানো এবং এসসিআইয়ের বিশেষ ক্যাসিং এড়িয়ে সমস্যার সমাধান করেছি:

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
@ মার্তিজজনপিটারস: বা আরও সহজ: open('filename', 'wb').write(json.dumps(d, ensure_ascii=False).encode('utf8'))এটি dumpsরিটার্ন ( অ্যাসিআই-ওয়াল) আরআর বা ইউনিকোড অবজেক্ট কিনা তা কাজ করে ।
jfs

@JFSebastian: ডান, কারণ str.encode('utf8') decodes পরোক্ষভাবে প্রথম। কিন্তু তাই unicode(data), যদি একটি strবস্তু দেওয়া হয় । :-) ব্যবহার io.open()আপনাকে বিওএম লেখার কোডেক ব্যবহার সহ আরও বিকল্প দেয় এবং আপনি অন্য কিছু দিয়ে জেএসওএন ডেটা অনুসরণ করছেন।
মার্টিজন পিটারস

@ মার্তিজজনপিটারস: বেসড .encode('utf8')ভেরিয়েন্টটি পাইথন 2 এবং 3 (একই কোড) উভয় ক্ষেত্রেই কাজ করে। unicodeপাইথন ৩-তে কোনও নেই Unre নিরবিচ্ছিন্ন: জসন ফাইলগুলি বিওএম ব্যবহার করা উচিত নয় (যদিও একটি নিশ্চিতকরণকারী জসন পার্সার বিওএমকে উপেক্ষা করতে পারে, 3983 খণ্ডিত দেখুন )।
জেএফএস

সমস্যা সমাধান করতে যোগ encoding='utf8'করা json.dumps। পিএস আমার ডাম্প করার জন্য একটি সিরিলিক পাঠ্য রয়েছে
ম্যাক্স এল

8

পাইথন ৩.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

নীচে আমার বুদ্ধিমানের উপরের উত্তর এবং গুগলের উত্তর বোঝা যাচ্ছে।

# 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]


1

এখানে মূল উত্তরের জন্য ধন্যবাদ। পাইথন 3 সহ নিম্নলিখিত কোডের লাইন:

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

ঠিক ছিল। যদি কোডটি অত্যাবশ্যক না হয় তবে কোডটিতে খুব বেশি লেখা না লেখার চেষ্টা করুন Consider

পাইথন কনসোলের জন্য এটি যথেষ্ট ভাল হতে পারে। তবে কোনও সার্ভারকে সন্তুষ্ট করার জন্য আপনাকে এখানে বর্ণিত লোকেল সেট করতে হবে (এটি যদি অ্যাপাচি 2 তে থাকে) http://blog.dscpl.com.au/2014/09/setting-lang-and-lcall-when-used .html

মূলত he_IL ইনস্টল করুন বা উবুন্টুতে যে কোনও ভাষার লোকেল ইনস্টল করুন এটি ইনস্টল করা হয়নি

locale -a 

এক্সএক্স যেখানে আপনার ভাষা সেখানে এটি ইনস্টল করুন

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'

আশা করি আপনি অ্যাপাচি থেকে পাইথন ত্রুটিগুলি যেমন পাবেন না:

মুদ্রণ (জেএস) ইউনিকোড এনকোড এরর: 'এসকিআই' কোডেক অক্ষরগুলি এনকোড করতে পারে না 41-45 পজিশনে: অমিতিকাল পরিসীমা নয় (128)

এছাড়াও অ্যাপাচিতে এখানে বর্ণিত হিসাবে ডিফল্ট এনকোডিংটি utf করার চেষ্টা করুন:
অ্যাপাচের জন্য ডিফল্ট এনকোডিংটি ইউটিএফ -8 এ কীভাবে পরিবর্তন করবেন?

তাড়াতাড়ি করুন কারণ অ্যাপাচি ত্রুটিগুলি ডিবাগ করার জন্য ব্যথা হতে পারে এবং আপনি ভুল করে ভাবতে পারেন যে এটি অজগর থেকে সম্ভবত সম্ভবত সেই পরিস্থিতিতে নয় from


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)

জ্যাঙ্গো টেমপ্লেটে জেএসএন ডেটা ব্যবহার করতে নীচের পদক্ষেপগুলি অনুসরণ করুন:

# 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অনির্ধারিত.
এএমসি

আইটি এখনই সংশোধন করা হয়েছে। এটি হবে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:   χαν  хан

আসল সংস্থান :https://blog.csdn.net/chuatony/article/details/72628868


-3

মার্টিজন দ্বারা নির্দেশিত হিসাবে নিশ্চিত করা হয়েছে যে জেসন.ডাম্পসে নিশ্চিত_এসিআই = মিথ্যা এই সমস্যাটি সমাধানের সঠিক দিক is তবে এটি একটি ব্যতিক্রম বাড়াতে পারে:

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

আপনার sys.getdefaultencoding () সঠিক সেট করতে আপনার সাইটইপি বা সাইটেকাস্টমাইজ.পী উভয় ক্ষেত্রে অতিরিক্ত সেটিংস দরকার। সাইট.py লাইব / পাইথন 2.7 / এর অধীনে এবং সাইটকাস্টমাইজ.পি লাইব / পাইথন 2.7 / সাইট-প্যাকেজগুলির আওতায় রয়েছে।

আপনি যদি ডেপ সেটেনকোডিং () এর আওতায় সাইট.পি ব্যবহার করতে চান: প্রথমটি যদি 0: থেকে 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()

আপনার সাইট.পি বা সাইটেকাস্টমাইজ.পি সেটিংস যাচাই করতে আপনার "ইউটিএফ -8" বা "ইউটিএফ -8" পাওয়া উচিত।

দয়া করে মনে রাখবেন যে ইন্টারেক্টিভ পাইথন কনসোলে আপনি sys.setdeafultencoding ("utf-8") করতে পারেন নি।


2
কোন। এটা করবেন না। ডিফল্ট ক্যারেক্টার এনকোডিং পরিবর্তন সঙ্গে কিছুই করার আছে jsonএর ensure_ascii=False। আপনি অন্যথায় মনে করেন যদি একটি ন্যূনতম সম্পূর্ণ কোড উদাহরণ সরবরাহ করুন।
jfs

আপনি কেবলমাত্র এই ব্যতিক্রমটি পান যদি আপনি হয় নন-এএসসিআইআই বাইট স্ট্রিংগুলি (যেমন ইউনিকোড মান নয়) ফিড করেন বা ফলত JSON মান (একটি ইউনিকোড স্ট্রিং) একটি নন-এসসিআইআই বাইট স্ট্রিংয়ের সাথে একত্রিত করার চেষ্টা করেন। ইউটিএফ -8 এ ডিফল্ট এনকোডিং সেট করা মূলত অন্তর্নিহিত সমস্যাটি মাস্কিং করা হয় যদি আপনি নিজের স্ট্রিং ডেটা সঠিকভাবে পরিচালনা না করে থাকেন।
মার্টিজন পিটারস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.