জেএসএন থেকে ইউনিকোডের পরিবর্তে স্ট্রিং অবজেক্টগুলি কীভাবে পাবেন?


276

আমি পাইথন 2 ব্যবহার করছি এএসসিআইআই এনকোডযুক্ত পাঠ্য ফাইলগুলি থেকে জেএসএনকে পার্স করার জন্য।

এই ফাইলগুলিকে হয় jsonবা দিয়ে লোড করার সময় simplejson, আমার সমস্ত স্ট্রিং মান স্ট্রিং অবজেক্টের পরিবর্তে ইউনিকোড অবজেক্টে কাস্ট করা হয়। সমস্যাটি হ'ল, আমাকে কয়েকটি লাইব্রেরির সাথে ডেটা ব্যবহার করতে হবে যা কেবল স্ট্রিং অবজেক্ট গ্রহণ করে। আমি গ্রন্থাগারগুলি পরিবর্তন করতে পারি না বা আপডেট করতে পারি না

ইউনিকোডের পরিবর্তে স্ট্রিং অবজেক্ট পাওয়া কি সম্ভব?

উদাহরণ

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

হালনাগাদ

এই প্রশ্নটি অনেক আগে জিজ্ঞাসা করা হয়েছিল , যখন আমি পাইথন 2 এর সাথে আটকে ছিলাম । আজকের জন্য একটি সহজ এবং পরিষ্কার সমাধান হ'ল পাইথনের সাম্প্রতিক সংস্করণ - অর্থাত পাইথন 3 এবং এগিয়ে ব্যবহার করা।


1
পাইথন 3 এর অধীনে কোনও সমস্যা নেই, নতুন তালিকাতে আইটেমগুলির ধরণটি হচ্ছেstr
GoingMyWay

1
পাইথন 3 কে 'পাইথনের সাম্প্রতিক সংস্করণ' নয়, এটি কেবল একটি বিকল্প শাখা।
ব্যবহারকারী 2589273

11
ডিসেম্বরে 2017 এ জাতীয় মন্তব্যটি দেখার জন্য এটি আশ্চর্যজনক - পাইথন 2 অবমূল্যায়ন করা হয়েছে এবং 12020
জার হাই

1
@ জারহাই অনেক লোক তাদের ইচ্ছার বিরুদ্ধে পাইথন 2 এ আটকে আছে। অনেকগুলি অ্যাপ্লিকেশন রয়েছে যা অটোমেশন এবং স্ক্রিপ্টিংয়ের জন্য তাদের নিজস্ব পাইথন সংস্করণ এম্বেড করে রাখে যাতে বিক্রেতার আপডেট হওয়া পর্যন্ত লোকেরা এটি ব্যবহার করতে হয় (আমি আপনাকে মায়া, হাউদিনী, নুকে দেখছি ..)
জর্ডি

1
@ জর্ডি আমি অবশ্যই এটি জানি এবং বুঝতে পারি। আমার মন্তব্য পরিভাষা সম্পর্কে ছিল - পাইথন একটি "বিকল্প শাখা" নয়, তবে দুর্ভাগ্যক্রমে যারা এর সাথে আটকে আছেন তাদের বিকল্পের (পাং উদ্দেশ্যে) অভাব রয়েছে।
জার হাই

উত্তর:


101

সঙ্গে একটি সমাধান object_hook

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 this is a unicode string, return its string representation
    if isinstance(data, unicode):
        return data.encode('utf-8')
    # 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.iteritems()
        }
    # 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'}

এটি কীভাবে কাজ করে এবং কেন আমি এটি ব্যবহার করব?

মার্ক অ্যামেরির কার্যকারিতা এইগুলির চেয়ে কম এবং স্বচ্ছ, সুতরাং এগুলি কী? আপনি কেন সেগুলি ব্যবহার করতে চান?

বিশুদ্ধরূপে জন্য কর্মক্ষমতা । মার্কের উত্তরটি ইউনিকোড স্ট্রিংয়ের সাথে প্রথমে জেএসএন পাঠ্যটিকে ডিকোড করে, তারপরে সমস্ত স্ট্রিংগুলিকে বাইট স্ট্রিংয়ে রূপান্তর করতে পুরো ডিকোড করা মানটির মাধ্যমে পুনরাবৃত্তি করে। এটিতে বেশ কয়েকটি অনাকাঙ্ক্ষিত প্রভাব রয়েছে:

  • সম্পূর্ণ ডিকোডেড কাঠামোর একটি অনুলিপি স্মৃতিতে তৈরি হয়
  • যদি আপনার JSON অবজেক্টটি সত্যই গভীরভাবে বাসা বেঁধেছে (500 স্তর বা তার বেশি) তবে আপনি পাইথনের সর্বাধিক পুনরাবৃত্তির গভীরতায় আঘাত হানবেন

এই উত্তরটি ঐ কর্মক্ষমতা বিষয় উভয় ব্যবহার করে হ্রাস object_hookএর প্যারামিটার json.loadএবং json.loadsদস্তাবেজগুলি থেকে :

object_hookএকটি alচ্ছিক ফাংশন যা কোনও বস্তুর আক্ষরিক ডিকোডড (এ dict) এর ফলাফলের সাথে ডাকা হবে । এর পরিবর্তে অবজেক্ট_হুকের রিটার্ন মান ব্যবহার করা হবে dict। এই বৈশিষ্ট্যটি কাস্টম ডিকোডারগুলি প্রয়োগ করতে ব্যবহার করা যেতে পারে

যেহেতু অন্যান্য অভিধান গভীর অনেক মাত্রা নেস্টেড অভিধান প্রেরণ পেতে object_hook হিসাবে তারা সঙ্কেতমুক্ত করছি , আমরা যে সময়ে তাদের ভিতরে কোন স্ট্রিং বা তালিকা byteify এবং পরে গভীর পুনরাবৃত্তির জন্য প্রয়োজন এড়াতে পারবেন।

মার্কের উত্তর যেমন object_hookদাঁড়ায় তেমন ব্যবহারের জন্য উপযুক্ত নয় কারণ এটি নেস্টেড ডিকশনারিগুলিতে পুনরাবৃত্তি করে। আমরা ignore_dictsপ্যারামিটারের সাথে এই উত্তরে সেই পুনরাবৃত্তিটি রোধ করি _byteify, যা এটিকে বাইটাইফ করার জন্য নতুন পাস করার সময় ব্যতীত সর্বদা object_hookপাস হয়ে যায় dictignore_dictsপতাকা বলে _byteifyউপেক্ষা করার dictযেহেতু তারা ইতিমধ্যে byteified হয়েছে সে।

অবশেষে, ফলাফল থেকে আমাদের বাস্তবায়ন json_load_byteifiedএবং json_loads_byteifiedকল _byteify(সহ ignore_dicts=True) ফিরে এসেছে json.loadবা json.loadsJSON পাঠ্যটি ডিকোড হচ্ছে এমন কেসটি dictপরিচালনা করতে শীর্ষ স্তরে নেই।


1
এখানে পদ্ধতির জন্য +1; আমি প্রথম যখন এটি পড়েছিলাম তখন আমি সত্যিই এটি উপলব্ধি করতে পারি নি তবে অবশেষে ট্র্যাভিস জেনসেনের উত্তরের আলোকে পুনরায় পড়ার সময় বুঝতে পেরেছিলাম। এটি কীভাবে কাজ করে এবং আমার উত্তরের এর সুবিধাগুলি কী তা পরিষ্কার করার প্রত্যাশায় আমি একটি দুর্দান্ত আক্রমণাত্মক সম্পাদনা করেছি। কোডটির মূল ধারণাটি অচ্ছুত রয়ে গেছে, তবে আমি অন্য সমস্ত কিছু পরিবর্তন করেছি। আপনি যদি এটিকে আপত্তি জানাতে নির্দ্বিধায় আমার সম্পাদনাটি করেন - এটি আপনার উত্তর!
মার্ক অ্যামেরি

সমস্যা নেই মার্ক, অনেক ধন্যবাদ। আমি আপনার সম্পাদনা পছন্দ, এটি আমার আসল তুলনায় অনেক বেশি ব্যাখ্যামূলক। হতে পারে, একদিন, আমি আরও সংক্ষিপ্ত উত্তর দিতে শিখব।
মিরেক মিসকুফ

2
এটি দুর্দান্ত সমাধান; দক্ষ এবং মার্জিত। : কিন্তু, আপনি যদি পাইথন <2.7 রাজত্ব আটকে করছি, যেমন আমি, আপনি লাইন প্রতিস্থাপন করার প্রয়োজন হবে return { byteify(key, ignore_dicts=True): _byteify(value, ignore_dicts=True) for key, value in data.iteritems() }সঙ্গে return dict((_byteify(key, ignore_dicts=True), _byteify(value, ignore_dicts=True)) for key, value in data.iteritems())এটি কাজ করে।
রিচার্ড ডান

আমি মনে করি আপনি পুনরাবৃত্তি গভীরতার সমস্যা সম্পর্কে ভুল about পুলিশের, আমি 990 পর্যন্ত যেতে পারেন: json_loads_byteified('[' * 990 + ']' * 990)। 991 এর সাথে এটি ক্র্যাশ হয়েছে। মার্ক এর এখনও 991: এর সাথে কাজ করে byteify(json.loads('[' * 991 + ']' * 991))। এটি 992-এ ক্র্যাশ হয়েছে So সুতরাং অন্তত এই পরীক্ষায়, মার্কগুলি আরও বেশি গভীরতর হতে পারে, আপনি যা বলেছেন তার বিপরীতে।
স্টিফান পোচম্যান 21

@ মার্ক অ্যামেরি আমার উপরের মন্তব্য সম্পর্কে আপনি কী ভাবেন? (আমি সম্পাদনার ইতিহাসে সবেমাত্র দেখেছি যে এই দাবিটি আসলে আপনিই ছিলেন)
স্টেফান পোচম্যান 21

180

এখানে কিছু ভাল উত্তর থাকার সময়, আমি আমার জেএসওএন ফাইলগুলি বিশ্লেষণের জন্য পাইওয়ামএল ব্যবহার করে শেষ করেছি, কারণ এটি strটাইপের পরিবর্তে কীগুলি এবং মানগুলি টাইপ স্ট্রিং হিসাবে দেয় unicode। কারণ JSON হ'ল YAML এর একটি উপসেট এটি দুর্দান্তভাবে কাজ করে:

>>> import json
>>> import yaml
>>> list_org = ['a', 'b']
>>> list_dump = json.dumps(list_org)
>>> list_dump
'["a", "b"]'
>>> json.loads(list_dump)
[u'a', u'b']
>>> yaml.safe_load(list_dump)
['a', 'b']

মন্তব্য

যদিও কিছু বিষয় লক্ষণীয়:

  • আমি স্ট্রিং অবজেক্টগুলি পাই কারণ আমার সমস্ত এন্ট্রি ASCII এনকোডযুক্ত । আমি যদি ইউনিকোড এনকোডযুক্ত এন্ট্রি ব্যবহার করি তবে আমি তাদের ইউনিকোড বস্তু হিসাবে ফিরিয়ে আনতে পারি - কোনও রূপান্তর নেই!

  • আপনার (সম্ভবত সর্বদা) পাইওয়ামএল এর safe_loadফাংশন ব্যবহার করা উচিত ; আপনি যদি এটি JSON ফাইলগুলি লোড করতে ব্যবহার করেন তবে আপনার loadকোনওভাবেই ফাংশনের "অতিরিক্ত শক্তি" লাগবে না।

  • আপনি যদি কোনও ওয়াইএএমএল পার্সার চান তবে এর অনুমানের 1.2 সংস্করণটির আরও বেশি সমর্থন রয়েছে (এবং সঠিকভাবে খুব কম সংখ্যাকে পার্স করা হয়েছে ) রুয়েমেল ওয়াইএমএল চেষ্টা করুন : pip install ruamel.yamlএবং import ruamel.yaml as yamlআমার পরীক্ষাগুলিতে আমার যা দরকার ছিল তা সবই ছিল।

রূপান্তর

যেমন বলা হয়েছে, কোনও রূপান্তর নেই! আপনি যদি কেবল এএসসিআইআই মানগুলির সাথে ডিল করার বিষয়ে নিশ্চিত হতে না পারেন (এবং আপনি বেশিরভাগ সময় নিশ্চিত হতে পারেন না) তবে একটি রূপান্তর ফাংশনটি আরও ভালভাবে ব্যবহার করুন :

আমি মার্ক অ্যামেরির একটি এখন কয়েকবার ব্যবহার করেছি, এটি দুর্দান্ত কাজ করে এবং এটি ব্যবহার করা খুব সহজ। আপনি এর object_hookপরিবর্তে অনুরূপ ফাংশনও ব্যবহার করতে পারেন , কারণ এটি আপনাকে বড় ফাইলগুলিতে পারফরম্যান্স বাড়িয়ে তুলতে পারে। এর জন্য মিরেক মিসকুফের সামান্য আরও জড়িত উত্তর দেখুন ।


8
আপনি যদি এই উত্তরটি ব্যবহার করার সিদ্ধান্ত নেন তবে একটু যত্ন নিন। এটি ব্রুটাসের ক্ষেত্রে পুরোপুরি কার্যকরভাবে কাজ করে, তবে কেবল কারণ তিনি জানেন যে তার ডেটাতে কেবল ASCII- এনকোডেবল অক্ষর রয়েছে। আপনার যদি সেই গ্যারান্টি না থাকে তবে এই উত্তরটি কার্যকর হবে না। উদাহরণস্বরূপ, yaml.load(json.dumps([u'a', u'£', u'É']))পাইথন শেলটি চালানোর চেষ্টা করুন এবং দেখুন যে আপনি ফিরে পেয়েছেন ['a', u'\xa3', u'\xc9'](যার মধ্যে unicodeস্ট্রিং রয়েছে )। আপনি যদি নিশ্চিত হতে না পারেন যে আপনার ডেটাতে কেবল ASCII অক্ষর সেট থেকে অক্ষর রয়েছে তবে তার পরিবর্তে আপনার আলাদা পদ্ধতির ব্যবহার করা উচিত (আমি আমার নিজের উত্তরের প্রস্তাব দিই)।
মার্ক আমেরিকা

1
ওয়াইএএমএল [u'a', u'b']সতর্কতা অবলম্বন করে।
কার্লোস কলা

1
এটি দুর্দান্ত, তবে এটি কম সংখ্যার সাথে কাজ করে না .. এখানে দেখুন: stackoverflow.com/questions/30458977/…
ওরেেন

@Oren এই একটি ত্রুটি নয় YAML বৈশিষ্ট কিন্তু PyYAML পার্সার হবে। Ruamel থেকে YAML পার্সার কাজ করে।
ব্রুটাস

আমি ["ক", "বি"] এর মতো ['এ', 'বি'] পছন্দ না করে @ ব্রুটাস
ব্যবহারকারী 60679

141

জিসন মডিউল ফাংশনগুলি ইউনিকোড স্ট্রিংয়ের পরিবর্তে বাইট স্ট্রিংগুলি ফিরিয়ে আনার জন্য কোনও বিল্ট-ইন বিকল্প নেই। তবে, এই সংক্ষিপ্ত এবং সাধারণ পুনরাবৃত্তি ফাংশনটি ইউনিকোড স্ট্রিংগুলি ইউটিএফ-8-এনকোডড বাইট স্ট্রিংগুলিতে কোনও ডিকোডেড জেএসএন বস্তুকে রূপান্তর করবে:

def byteify(input):
    if isinstance(input, dict):
        return {byteify(key): byteify(value)
                for key, value in input.iteritems()}
    elif isinstance(input, list):
        return [byteify(element) for element in input]
    elif isinstance(input, unicode):
        return input.encode('utf-8')
    else:
        return input

আপনি আউটপুট এ কেবল কল করুন json.loadবা json.loadsকল করুন।

কয়েকটি নোট:

  • পাইথন 2.6 সমর্থনে বা আগে, প্রতিস্থাপন return {byteify(key): byteify(value) for key, value in input.iteritems()}সঙ্গে return dict([(byteify(key), byteify(value)) for key, value in input.iteritems()]), যেহেতু অভিধান comprehensions পাইথন 2.7 পর্যন্ত সমর্থিত হয়নি।
  • যেহেতু এই উত্তরটি পুরো ডিকোডড অবজেক্টের মাধ্যমে পুনরাবৃত্তি হয়, এর মধ্যে বেশ কয়েকটি অনাকাঙ্ক্ষিত পারফরম্যান্স বৈশিষ্ট্য রয়েছে যা খুব সাবধানে object_hookবা object_pairs_hookপরামিতি ব্যবহার করে এড়ানো যায় । মিরেক মিসকুফের উত্তর এখন পর্যন্ত কেবলমাত্র এটিই সঠিকভাবে এটিকে পরিচালনা করতে সক্ষম, যদিও এর পরিণতি হিসাবে এটি আমার পদ্ধতির চেয়ে উল্লেখযোগ্যভাবে জটিল।

1
আমি এটি পছন্দ করি - এটি কোনও উপেক্ষা নয় - এটি স্বীকৃতি দেয় যে লোকেরা যখন "স্ট্রিং" এবং "এসকিআই" বলে তখন তারা বেশিরভাগ নির্লজ্জতার সাথে বোঝায় যে তারা বাইট চেয়েছিলেন, তাত্ত্বিক ইউনিকোডের অক্ষর নয়। (এবং তারা এখনও অন্য প্রান্তে পাউন্ডের লক্ষণগুলিকে চেয়েছিল বলে ascii নয়)
ড্যানি স্ট্যাপল

আমি এটি পছন্দ করি, এটি প্রায় আমার প্রিন্টারের কাজ মতো একইভাবে কাজ করে, যেহেতু আমি জানি যে জসন টিপল তৈরি করে না, তাই আপনারও টিউপলের ব্যতিক্রম যুক্ত করা উচিত।
y.petremann

এটি মারাত্মকভাবে অক্ষম, আপনাকে বারবার ক্রমবর্ধমান নোডগুলির প্রয়োজন হয় যা আপনার প্রয়োজন হয় না। জাসন মডিউল আপনাকে আরও বেশি দক্ষতার সাথে এটি করার জন্য হুক দেয়। নীচের উত্তরটি ব্যবহার করার object_hookচেয়ে প্রকৃতপক্ষে এটির চেয়ে আরও খারাপ, তবে, ব্যবহার করে object_pairs_hookআপনি যুক্তিসঙ্গতভাবে কার্যকর পদ্ধতি নিয়ে আসতে পারেন যার জন্য স্ট্রস না ​​থাকা নোডের পুনরাবৃত্তি বা পুনর্বিবেচনার প্রয়োজন নেই।
ট্র্যাভিস জেনসেন

1
পছন্দ করুন এই object_pairs_hookপদ্ধতির চেয়ে পদ্ধতিটি সম্ভবত সামান্য কঠিন (আপনার প্যারামিটারটি কীভাবে কাজ করে তা বুঝতে হবে এবং তালিকাগুলি এবং ডিক্টগুলি কেন বিভিন্ন হ্যান্ডলিংয়ের প্রয়োজন হয়) এবং পারফরম্যান্সের সুবিধাটি বেশিরভাগ লোকের পক্ষে বিবেচিত হবে না ... তবে আমি আশা করব এটি বিদ্যমান, বিশেষত যে কেউ অস্বাভাবিকভাবে গভীরভাবে নেস্ট করা জেএসএন বিষয়বস্তু নিয়ে কাজ করছেন।
মার্ক আমেরিকা

Plus1 এটি সর্বাধিক সংক্ষিপ্ত উত্তর; পাইওয়ামএল ইনস্টল করার জন্য একটি ব্যথা besides কেবলমাত্র রূপান্তরকে মাইক্রো-স্ট্রিম করাটাই সবচেয়ে ভাল হবে যাতে এটি 4 এক্স মেমরি ব্যবহার করে না।
ব্যক্তিগত_ক্লাউড

74

আপনি একটি রূপান্তরকারী পাস করার object_hookজন্য প্যারামিটার ব্যবহার করতে পারেন json.loads। সত্যের পরে আপনাকে রূপান্তর করতে হবে না। jsonমডিউলটি সর্বদা কেবল object_hookডিকটগুলিকেই পাস করবে এবং এটি পুনরাবৃত্তভাবে নেস্টেড ডিক্টগুলিতে পাস করবে, সুতরাং আপনাকে নিজেকে নেস্টেড ডিক্টসে পুনরুক্তি করতে হবে না। আমি মনে করি না আমি ইউনিকোড স্ট্রিংগুলিকে ওয়েলস শোয়ের মতো সংখ্যায় রূপান্তর করব। যদি এটি একটি ইউনিকোড স্ট্রিং হয় তবে এটি JSON ফাইলে একটি স্ট্রিং হিসাবে উদ্ধৃত হয়েছিল, সুতরাং এটি একটি স্ট্রিং (বা ফাইলটি খারাপ) বলে মনে করা হচ্ছে।

এছাড়াও, আমি ভালো কিছু করছেন এড়ানোর চেষ্টা চাই str(val)একটি উপর unicodeবস্তু। value.encode(encoding)আপনার বাহ্যিক কাজটি কী প্রত্যাশা করে তার উপর নির্ভর করে আপনার একটি বৈধ এনকোডিং ব্যবহার করা উচিত ।

সুতরাং, উদাহরণস্বরূপ:

def _decode_list(data):
    rv = []
    for item in data:
        if isinstance(item, unicode):
            item = item.encode('utf-8')
        elif isinstance(item, list):
            item = _decode_list(item)
        elif isinstance(item, dict):
            item = _decode_dict(item)
        rv.append(item)
    return rv

def _decode_dict(data):
    rv = {}
    for key, value in data.iteritems():
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        elif isinstance(value, list):
            value = _decode_list(value)
        elif isinstance(value, dict):
            value = _decode_dict(value)
        rv[key] = value
    return rv

obj = json.loads(s, object_hook=_decode_dict)

3
এটি ঠিক আছে যদি এর অবজেক্টটি sJSON হয় Object(কীটির একটি আনর্ডারড কালেকশন: ':' অক্ষরটি কী এবং মানকে পৃথক করে, কমা দ্বারা পৃথক এবং কোঁকড়া ধনুর্বন্ধনীতে আবদ্ধ) তবে এটি যদি না হয় তবে বলুন জেএসওএন Array। তাই আপনি যদি একটি JSON- দেওয়া Arrayমত ["a", "b"], ফলে এখনও হতে হবে [u'a', u'b']। বর্তমানে উপলব্ধ কাস্টমাইজিং হুক-প্রকারের প্যারামিটারগুলির জন্য json.loads()আর কোনও পাওয়া যায় না।
মার্টিনো

2
যেহেতু, আপনি উল্লিখিত হিসাবে, jsonমডিউলটি ঘন ঘন নেস্টেডগুলিতে পাস করবে dict, সুতরাং তাদের দুটি ফাংশনে এটি পরীক্ষা করা অপ্রয়োজনীয় - সুতরাং যে দুটি elifধারা তাদের জন্য পরীক্ষা করে তা অপসারণ করা উচিত।
মার্টিনো

1
নোট করুন যে একটি আন্ডারস্কোর দিয়ে ফাংশন নাম শুরু করার আমদানি বিবৃতিগুলির একটি বিশেষ অর্থ রয়েছে। আপনি যদি ইউটিলিটি.পি নামে একটি ফাইলে এই ফাংশনগুলি রাখেন এবং অন্য কোনও ফাইলে করেন from Utility import *, তবে আন্ডারস্কোরের কারণে ফাংশনগুলি দেখা যাবে না
এম কাটজ

1
এটি সত্যিই খারাপ ধারণা। object_hookপ্রতিটি জেসন অবজেক্টকে পার্স করার জন্য ডেকে আনা হয়, সুতরাং যদি আপনি যা দেওয়া হয় তার পুনরাবৃত্তি করেন, আপনি ইতিমধ্যে "বাইটাইফাইড" জিনিসগুলিকে পুনরায় "বাইটাইফিং" করছেন are পারফরম্যান্স বস্তুর আকারের সাথে জ্যামিতিকভাবে বৃদ্ধি পেতে চলেছে। আমি এখানে একটি উত্তর অন্তর্ভুক্ত করেছি যা ব্যবহার করে object_pairs_hookএবং সেই সমস্যায় ভোগেনা।
ট্র্যাভিস জেনসেন

38

কারণ জেসনের স্ট্রিং অবজেক্ট এবং ইউনিকোড অবজেক্টের মধ্যে কোনও পার্থক্য নেই। এগুলি জাভাস্ক্রিপ্টে সমস্ত স্ট্রিং।

আমি মনে করি জেএসওন ইউনিকোড অবজেক্টগুলি ফিরিয়ে দেওয়া ঠিক । আসলে, আমি কিছু স্বীকার করতে চান না কম, যেহেতু জাভাস্ক্রিপ্ট স্ট্রিং আসলে হয় unicodeবস্তু (যেমন তাদেরকে JSON (জাভাস্ক্রিপ্ট) স্ট্রিং সংরক্ষণ করতে পারেন যে কোন ধরণের ইউনিকোড চরিত্রের) তাই এটি তৈরি করতে ইন্দ্রিয় তোলে unicodeযখন তাদেরকে JSON থেকে স্ট্রিং অনুবাদ বস্তু। সাধারণ লাইনের স্ট্রিংগুলি খাপ খায় না কারণ লাইব্রেরিতে আপনার যে এনকোডিংটি রয়েছে তা অনুমান করতে হবে।

unicodeস্ট্রিং অবজেক্টগুলি সর্বত্র ব্যবহার করা ভাল । সুতরাং আপনার সর্বোত্তম বিকল্পটি হ'ল আপনার গ্রন্থাগারগুলি আপডেট করা যাতে তারা ইউনিকোড অবজেক্টগুলির সাথে ডিল করতে পারে।

তবে আপনি যদি সত্যই বাইটস্ট্রিং করতে চান তবে ফলাফলগুলি আপনার পছন্দসই এনকোডিংয়ে এনকোড করুন:

>>> nl = json.loads(js)
>>> nl
[u'a', u'b']
>>> nl = [s.encode('utf-8') for s in nl]
>>> nl
['a', 'b']

ধন্যবাদ নসক্লো, আমি এটিই প্রথম করেছি। তবে যেমনটি আমি বলেছি, আসল ডেটা আমি ব্যবহার করেছি তা খুব সুন্দর এবং খুব সুন্দর, তাই এটি কিছুটা ওভারহেডের প্রবর্তন করেছিল। আমি এখনও একটি স্বয়ংক্রিয় সমাধান খুঁজছি ... সেখানে কমপক্ষে একটি বাগ রিপোর্ট রয়েছে যেখানে লোকেরা ইউনিকোডের পরিবর্তে স্ট্রিং অবজেক্টগুলি সিম্পজসন ফেরত দেওয়ার বিষয়ে অভিযোগ করে।
ব্রুটাস

1
@ ব্রুটাস: আমি মনে করি জিসন ইউনিকোড বস্তু ফিরিয়ে দেওয়া ঠিক is আসলে, আমি কম কিছু গ্রহণ করব না, কারণ জাভাস্ক্রিপ্টের স্ট্রিংগুলি আসলে ইউনিকোড অবজেক্ট। আমার অর্থ হ'ল জসন (জাভাস্ক্রিপ্ট) স্ট্রিংগুলি যে কোনও ধরণের ইউনিকোড চরিত্র সংরক্ষণ করতে পারে, তাই জসন থেকে অনুবাদ করার সময় ইউনিকোড অবজেক্ট তৈরি করা বুদ্ধিমান হয়ে যায়। পরিবর্তে আপনার সত্য আপনার লাইব্রেরি ঠিক করা উচিত।
নোকস্কো

16

চারপাশে একটি সহজ কাজ বিদ্যমান।

TL; DR - এর ast.literal_eval()পরিবর্তে ব্যবহার করুন json.loads()। উভয়ই astএবং jsonস্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে।

কোনও 'নিখুঁত' উত্তর না হলেও, আপনি যদি ইউনিকোডকে পুরোপুরি উপেক্ষা করার পরিকল্পনা করেন তবে এটি একদম কাছে যায়। পাইথনে ২.7

import json, ast
d = { 'field' : 'value' }
print "JSON Fail: ", json.loads(json.dumps(d))
print "AST Win:", ast.literal_eval(json.dumps(d))

দেয়:

JSON Fail:  {u'field': u'value'}
AST Win: {'field': 'value'}

যখন কিছু বস্তু সত্যই ইউনিকোড স্ট্রিং থাকে তখন এটি আরও লোমশ হয়। পুরো উত্তরটি চুল লোমশ হয়ে যায়।


11
বেটার নিশ্চিত করা আপনার JSON কোন ধারণ করে না null, trueঅথবা falseমূল্যবোধ, কারণ তারা পাইথন বৈধ নয় এবং কারণ হবে literal_eval()ব্যর্থ।
ɈsәɹoɈ

3
@ ʇsәɹoɈ আরও ভাল আশা করুন যে আপনার JSON এ \/একটি স্ট্রিংয়ের ভিতরে একটি পালিয়ে যাওয়া কঠিন ( ) বা একটি ইউনিকোড পালানোর অনুক্রম (যেমনটি "\u0061"লেখার অন্য উপায় "a") নেই। পাইথনের আক্ষরিক বাক্য গঠন বেশ কয়েকটি উপায়ে জেএসএনের সাথে সামঞ্জস্যপূর্ণ নয় এবং আমি কোনও উত্তরই ফেলে দিতে যাচ্ছি না এমন কোনও স্ক্রিপ্টের জন্য আমি এই উত্তরটিতে বিশ্বাস করব না।
মার্ক আমেরিকা

লোকেরা ঠিক বলেছেন যে যদি স্ট্রিংটি সত্যই ইউনিকোড হয় তবে এই উত্তরটি ব্যর্থ হয়, তবে যদি তা হয় তবে আমরা কোনওভাবেই কোনও স্ট্রিংয়ে কাস্ট করতে সক্ষম হব না। এমন উত্তরের জন্য +1 যা কেবল তখনই কাজ করে যখন এটি কাজ করে এবং অন্যথায় ব্যতিক্রম ছুঁড়ে ফেলে
স্টিফান সুলিভান

সম্ভব jsonহলে ডেটা ডাম্প করার জন্য ব্যবহার করবেন না , printঅজগর চালানো হলে কেবল ব্যবহার করুন । তারপরে ast.literal_evalকাজ করে
জিন-ফ্রান্সোইস ফ্যাব্রে

11

মাইক ব্রেনানের উত্তর নিকটবর্তী, তবে পুরো কাঠামোটিকে পুনরায় অতিক্রম করার কোনও কারণ নেই। আপনি যদি object_hook_pairs(পাইথন ২.7++) প্যারামিটারটি ব্যবহার করেন :

object_pairs_hookanচ্ছিক ফাংশন যা জোড়গুলির অর্ডারযুক্ত তালিকার সাথে আক্ষরিক ডিকোড করা কোনও বস্তুর ফলাফলের সাথে ডাকা হবে। এর object_pairs_hookপরিবর্তে এর মানটি ব্যবহার করা হবে dict। এই বৈশিষ্ট্যটি কাস্টম ডিকোডারগুলি প্রয়োগ করতে ব্যবহার করা যেতে পারে যা কী এবং মান জোড়গুলি ডিকোড করা হয় এমন আদেশের উপর নির্ভর করে (উদাহরণস্বরূপ, collections.OrderedDictসন্নিবেশের ক্রমটি মনে রাখবে)। যদি object_hookএটিও সংজ্ঞায়িত করা হয় তবে object_pairs_hookঅগ্রাধিকার গ্রহণ করে।

এটির সাহায্যে আপনি প্রতিটি JSON অবজেক্ট আপনার হাতে তুলে ধরেন, যাতে আপনি পুনরাবৃত্তির কোনও প্রয়োজন ছাড়াই ডিকোডিংটি করতে পারেন:

def deunicodify_hook(pairs):
    new_pairs = []
    for key, value in pairs:
        if isinstance(value, unicode):
            value = value.encode('utf-8')
        if isinstance(key, unicode):
            key = key.encode('utf-8')
        new_pairs.append((key, value))
    return dict(new_pairs)

In [52]: open('test.json').read()
Out[52]: '{"1": "hello", "abc": [1, 2, 3], "def": {"hi": "mom"}, "boo": [1, "hi", "moo", {"5": "some"}]}'                                        

In [53]: json.load(open('test.json'))
Out[53]: 
{u'1': u'hello',
 u'abc': [1, 2, 3],
 u'boo': [1, u'hi', u'moo', {u'5': u'some'}],
 u'def': {u'hi': u'mom'}}

In [54]: json.load(open('test.json'), object_pairs_hook=deunicodify_hook)
Out[54]: 
{'1': 'hello',
 'abc': [1, 2, 3],
 'boo': [1, 'hi', 'moo', {'5': 'some'}],
 'def': {'hi': 'mom'}}

লক্ষ্য করুন যে আমাকে কখনই পুনরাবৃত্তভাবে কল করতে হবে না যেহেতু আপনি যখন ব্যবহার করবেন তখন প্রতিটি বস্তু হুকের হাতে চলে যাবে object_pairs_hook। আপনাকে তালিকাগুলির বিষয়ে যত্নশীল হতে হবে তবে আপনি দেখতে পাচ্ছেন যে তালিকার মধ্যে থাকা কোনও জিনিস সঠিকভাবে রূপান্তরিত হবে এবং এটি ঘটতে আপনাকে পুনরাবৃত্তি করতে হবে না।

সম্পাদনা: একজন সহকর্মী দেখিয়েছেন যে পাইথন 2.6 নেই object_hook_pairs। আপনি এখনও খুব ছোট পরিবর্তন করে এই উইল পাইথন 2.6 ব্যবহার করতে পারেন। উপরের হুকটিতে, পরিবর্তন করুন:

for key, value in pairs:

প্রতি

for key, value in pairs.iteritems():

তার object_hookপরিবর্তে ব্যবহার করুন object_pairs_hook:

In [66]: json.load(open('test.json'), object_hook=deunicodify_hook)
Out[66]: 
{'1': 'hello',
 'abc': [1, 2, 3],
 'boo': [1, 'hi', 'moo', {'5': 'some'}],
 'def': {'hi': 'mom'}}

object_pairs_hookJSON অবজেক্টের প্রতিটি অবজেক্টের জন্য একটি কম অভিধানে ফলাফল ব্যবহার করা , যা আপনি যদি একটি বিশাল ডকুমেন্টকে বিশ্লেষণ করে থাকেন তবে কিছুটা হলেও মূল্যবান হতে পারে।


1
এটি ঝরঝরে এবং সবুজ চেকমার্কের প্রাপ্যের খুব কাছাকাছি বলে মনে হচ্ছে (আরও ভাল উত্তর এসেছে বলে ব্রুটাস ইতিমধ্যে উদারপন্থী হয়ে গেছে)। তবে ... deunicodify_hookআপনি এই উত্তরে যে চিত্র প্রদর্শন করছেন তাতে কেন সঠিকভাবে তালিকাগুলি পরিচালনা করবেন না ? এই মুহুর্তে, আপনার একটি প্রয়োগ রয়েছে deunicodify_hookযা তালিকার উপরে পুনরাবৃত্তি করে না এবং সেগুলির মধ্যে থাকা স্ট্রিংগুলি এবং তালিকাগুলি ডিওনিকোডাইফাই করে না এবং এইভাবে আপনি যে আউটপুটটি প্রদর্শন করছেন তা আপনার হুক আসলে উত্পন্ন আউটপুটটির সাথে মেলে না । এটি ঠিক করুন, এবং এই উত্তরটি আমার চেয়ে সেরা।
মার্ক অ্যামেরি

অপ্রয়োজনীয়: আমি এখানে সিপিথন দোভাষী দিয়ে ফাংশনটি প্রদর্শন করার পরামর্শ দিচ্ছি যা আপনি এখানে ব্যবহার করছেন (যা আমি আয়রন পাইথন বলে মনে করি)? সিপিথন দোভাষীটি বেশিরভাগ পাইথন ব্যবহারকারীদের কাছে বেশি পরিচিত এবং আমার মতে, এটি প্রিটিওর।
মার্ক অ্যামেরি

এটি আমার পক্ষে কাজ করে না তবে আমি নিশ্চিত যে আমি যা করছি তার কিছুটা স্পর্শ ... আমি একটি বৃহত জসন ডক থেকে একটি ফাইলে একটি তালিকা সংরক্ষণ করছি। আমি এই অবজেক্ট_ পেয়ার_হুকের সাথে বা এটি লোড না করেই, প্রতিটি আইটেম ইউনিকোডে আসে। অভিশাপ।
RSS

1
@ বার্সা ভাল পয়েন্ট! যেহেতু object_pairs_hookশুধুমাত্র আহ্বান পরার বস্তু , যদি আপনার তাদেরকে JSON টেক্সট শীর্ষ স্তরে স্ট্রিং একটি তালিকা আছে, এই সমাধান ব্যর্থ হবে। যে জিনিসটি থেকে ফিরে এসেছিল তাতে কোনও ফাংশন কল না করে এটি ঠিক করার কোনও উপায় নেই json.load; কোনও json.loadহুক গ্যারান্টি দিতে পারে না যে আপনি প্রতিটি স্ট্রিংয়ের সাথে ডিল করতে পারবেন। আমি মনে করি এটি আমার পক্ষে হুকগুলি ব্যবহারের ক্ষেত্রে আমার সমাধানের প্রস্তাব দেওয়ার পক্ষে যথেষ্ট ত্রুটি।
মার্ক আমেরিকা

-১ কারণ আমি কেবল বুঝতে পেরেছি যে মিরেক মিসকুফ ইতিমধ্যে একটি অবজেক্ট-হুক উত্তর পোস্ট করেছেন যে মাইক ব্রেন্নানের পদ্ধতির কোনও অসুবিধাগুলি নেই (একই অভিধানকে একাধিকবার পুনরায় বিভাজন দেয়) বা এর একটিও নেই (নেস্টেড তালিকা বা শীর্ষ-স্তরের তালিকাগুলি বাইটাইফ করতে ব্যর্থ হয়েছে) বা স্ট্রিং)। আমি নিশ্চিত নই যে কেন তার উত্তর প্রায় কোনও মনোযোগ দিয়েই স্থির হয়ে গেছে যদিও এই উত্তরটি - যা নিকৃষ্ট - দ্রুত ভোট পেয়েছে।
মার্ক

9

আমি ভয় পাচ্ছি যে সিম্পজসন লাইব্রেরিতে স্বয়ংক্রিয়ভাবে এটি অর্জন করার কোনও উপায় নেই।

সিম্পজসনে স্ক্যানার এবং ডিকোডারটি ইউনিকোড পাঠ্য তৈরি করার জন্য তৈরি করা হয়েছে। এটি করতে, গ্রন্থাগারটি c_scanstring(যদি এটি উপলব্ধ থাকে, গতির জন্য) নামে একটি ফাংশন ব্যবহার করে বা py_scanstringসি সংস্করণ উপলব্ধ না হয়। scanstringফাংশন প্রায় প্রতি রুটিন simplejson একটি কাঠামো, যা টেক্সট থাকতে পারে ডিকোড করার জন্য আছে যা দ্বারা বেশ কয়েকবার বলা হয়। আপনি হয় সিম্পজসন.ডেকোডার scanstring, বা সাবক্লাসে মানকিপ্যাচ করতে হবে JSONDecoderএবং পাঠ্য থাকতে পারে এমন কোনও কিছুতে নিজের সম্পূর্ণ বাস্তবায়ন দিতে হবে।

কারণ simplejson আউটপুট ইউনিকোড অবশ্য যে JSON বৈশিষ্ট বিশেষভাবে উল্লেখ করেছেন যে "একজন স্ট্রিং শূন্য বা তার বেশি ইউনিকোড অক্ষর একটি সংগ্রহ" ... ইউনিকোড সমর্থন বিন্যাস নিজেই অংশ হিসেবে অধিকৃত হয়। সিম্পলজসন এর scanstringবাস্তবায়ন ইউনিকোড পলায়নের স্ক্যান এবং ব্যাখ্যা করতে এতদূর এগিয়ে গেছে (এমনকি ত্রুটি-চেক- বিচ্যুত মাল্টি-বাইট চার্সেট উপস্থাপনার জন্যও), সুতরাং এটি আপনার কাছে মূল্যকে নির্ভরযোগ্যভাবে ফিরিয়ে দিতে পারে এমন একমাত্র উপায় যেমন ইউনিকোড।

আপনার যদি কোনও বয়স্ক গ্রন্থাগার strথাকে তবে এটির জন্য প্রয়োজনীয় পরামর্শ দেওয়ার জন্য আমি আপনাকে প্রস্তাব দিই যে পার্সিংয়ের পরে নেস্টেড ডেটা স্ট্রাকচারটি কঠোরভাবে অনুসন্ধান করুন (যা আমি স্বীকার করি যা আপনি স্পষ্টভাবে বলেছিলেন যে আপনি এড়াতে চেয়েছিলেন ... দুঃখিত), অথবা সম্ভবত আপনার লাইব্রেরিগুলি কোনও প্রকারে আবদ্ধ করুন সম্মুখভাগ যেখানে আপনি ইনপুট পরামিতিগুলিকে আরও দানাদার স্তরে ম্যাসেজ করতে পারেন। আপনার ডেটা স্ট্রাকচার সত্যিই গভীরভাবে বাসা বাঁধে যদি দ্বিতীয় পদ্ধতির প্রথমটির চেয়ে আরও বেশি পরিচালনাযোগ্য হতে পারে।


4

হিসাবে মার্ক (অ্যামেরি) সঠিকভাবে নোট করেছে: জাইসন ডাম্পের উপর পাইওয়ামেলের ডিসরিয়ালিজার ব্যবহার করা কেবলমাত্র আপনার যদি কেবল এএসসিআইআই থাকে তবে কাজ করে। কমপক্ষে বাক্সের বাইরে।

পাইওয়ামল পদ্ধতির বিষয়ে দুটি দ্রুত মন্তব্য:

  1. ক্ষেত্রের ডেটাতে কখনও yaml.load ব্যবহার করবেন না । কাঠামোর মধ্যে লুকানো স্বেচ্ছাসেবক কোড কার্যকর করতে এটি ইয়ামেলের একটি বৈশিষ্ট্য (!)।

  2. আপনি পারেন এটির মাধ্যমে এএসসিআইআই-তেও এটি কাজ করতে :

    def to_utf8(loader, node):
        return loader.construct_scalar(node).encode('utf-8')
    yaml.add_constructor(u'tag:yaml.org,2002:str', to_utf8)

তবে পারফরম্যান্সের ভিত্তিতে এটি মার্ক অ্যামেরির উত্তরের সাথে তুলনা করে না:

দুটি পদ্ধতিতে কিছু গভীরভাবে নেস্টেড নমুনা ছিদ্র ছুঁড়ে ফেলেছি, আমি এটি পেয়েছি (ডিটি [জে] = জেএসন.লোডস এর সময় ব-দ্বীপ (জসন.ডাম্পস (মি))):

     dt[yaml.safe_load(json.dumps(m))] =~ 100 * dt[j]
     dt[byteify recursion(Mark Amery)] =~   5 * dt[j]

সুতরাং গাছ পুরোপুরি হাঁটা সহ deserialization এবং এনকোডিং সি ভিত্তিক বাস্তবায়নের ক্রমমাত্রার ক্রম । আমি গভীরভাবে বাসা বাঁধা কাঠামোগুলিতে এই লক্ষণীয়ভাবে দ্রুত এবং এটি ইয়ামল লোডের চেয়েও বেশি দৃust় বলে মনে করি। এবং কম সুরক্ষা ত্রুটি প্রবণতা, yaml.load এ খুঁজছেন।

=> আমি কেবলমাত্র সি ভিত্তিক রূপান্তরকারীটির একটি পয়েন্টারের প্রশংসা করব বাইটটাইফ ফাংশনটির ডিফল্ট উত্তর হওয়া উচিত।

এটি যদি আপনার জসন কাঠামোটি ক্ষেত্র থেকে আসে তবে এটি ব্যবহারকারীদের ইনপুট সহ বিশেষত সত্য holds কারণ তখন আপনার সম্ভবত হাঁটার দরকার যাহাই হউক না কেন আপনার পছন্দসই অভ্যন্তরীণ তথ্য গঠন স্বাধীন (শুধুমাত্র 'ইউনিকোড স্যান্ডউইচ' বা বাইট স্ট্রিং) - আপনার গঠন করে।

কেন?

ইউনিকোড নরমালাইজেশন । অজ্ঞাত জন্য: ব্যাথার ঔষুধ খাও এবং পড়তে এই

সুতরাং বাইটাইফাই রিকার্সন ব্যবহার করে আপনি একটি পাথর দিয়ে দুটি পাখি মেরেছেন:

  1. নেস্টেড জসন ডাম্পগুলি থেকে আপনার বাইটস্ট্রিংগুলি পান
  2. ব্যবহারকারীর ইনপুট মানগুলি সাধারণীকরণ করুন, যাতে আপনি আপনার স্টোরেজে স্টাফগুলি খুঁজে পান।

আমার পরীক্ষায় এটি প্রমাণিত হয়েছে যে ইনপুট.এনকোড ('utf-8') কে ইউনিকোডেডাটা.অনর্মালাইজ ('এনএফসি', ইনপুট) দিয়ে প্রতিস্থাপন করা। এনকোড ('ইউটিএফ -8') ডাব্লু / ও এনএফসি-এর চেয়েও দ্রুত ছিল - তবে আমি অনুমান করি যে নমুনা ডেটার উপর ভারী নির্ভরশীল।


3

গোটাচা সেটাই simplejson এবং jsonএটি দুটি পৃথক মডিউল, অন্তত যেভাবে তারা ইউনিকোডের সাথে ডিল করে। আপনার কাছে jsonপাই ২.+++ রয়েছে এবং এটি আপনাকে ইউনিকোড মান দেয়, তবে simplejsonস্ট্রিং অবজেক্ট দেয়। আপনার পরিবেশে কেবল ইজি_ ইনস্টল-ইন সিম্পজসন চেষ্টা করুন এবং দেখুন এটি কার্যকর কিনা। এটা আমার জন্য।


2

ডাম্প এবং লোডের জন্য কেবল জসনের পরিবর্তে আচার ব্যবহার করুন:

    import json
    import pickle

    d = { 'field1': 'value1', 'field2': 2, }

    json.dump(d,open("testjson.txt","w"))

    print json.load(open("testjson.txt","r"))

    pickle.dump(d,open("testpickle.txt","w"))

    print pickle.load(open("testpickle.txt","r"))

এটি উত্পাদন করে আউটপুট (স্ট্রিং এবং পূর্ণসংখ্যা সঠিকভাবে পরিচালনা করা হয়):

    {u'field2': 2, u'field1': u'value1'}
    {'field2': 2, 'field1': 'value1'}

1
এমন সমাধানের জন্য +1 যা অতিরিক্ত প্যাকেজগুলির প্রয়োজন নেই (যেমন ইয়ামল )। তবে কখনও কখনও - আমার মূল ক্ষেত্রেটির মতো - আমারও জেএসএনে ডেটা থাকা দরকার, তাই আচার সবসময় সেরা বিকল্প নয়। তদুপরি, আপনি safe_loadওয়াইএএমএলে আছেন, আমি জানি না আচারের জন্য অনুরূপ কিছু উপস্থিত রয়েছে কিনা ।
ব্রুটাস

1

সুতরাং, আমি একই সমস্যা চালিয়েছি। অনুমান করুন যে প্রথম গুগলের ফলাফল কী ছিল।

যেহেতু পাইগটিকে আমার সমস্ত ডেটা পাঠাতে হবে, তাই ইউনিকোড স্ট্রিংগুলিও আমার পক্ষে খুব কার্যকর নয়। সুতরাং আমি অন্য পুনরাবৃত্ত রূপান্তর পদ্ধতি আছে। এটি টাইপসেফ জেএসওএন রূপান্তরকরণের জন্যও দরকার j যদিও ডিক সূচকগুলি রূপান্তর করে না।

# removes any objects, turns unicode back into str
def filter_data(obj):
        if type(obj) in (int, float, str, bool):
                return obj
        elif type(obj) == unicode:
                return str(obj)
        elif type(obj) in (list, tuple, set):
                obj = list(obj)
                for i,v in enumerate(obj):
                        obj[i] = filter_data(v)
        elif type(obj) == dict:
                for i,v in obj.iteritems():
                        obj[i] = filter_data(v)
        else:
                print "invalid object in data, converting to string"
                obj = str(obj) 
        return obj

ইউনিকোড থেকে রূপান্তরিত কোনও অভিধানে যদি আপনার কী প্রয়োজন হয় তবেই কেবল এখানে সমস্যা দেখা দিতে পারে। যদিও এই বাস্তবায়ন মানগুলিতে রূপান্তরিত করে, এটি ইউনিকোড কীগুলি বজায় রাখে। আপনি যদি একটি 'নেভোবজ' তৈরি করেন তবে নেউবোজ [টিআর (i)] = ... ব্যবহার করুন এবং আপনার কাজ শেষ হয়ে গেলে অজেক্ট = নেভোবজ নির্ধারণ করুন, কীগুলিও রূপান্তরিত হবে।
নিল স্ট্যুবলেন

কীগুলি রূপান্তর করার মাধ্যমে এটি উপলব্ধি বা আরও ভাল হতে পারে। এটি ইউনিডিওমেটিকও; এটি উভয় স্থানে বস্তুগুলিকে পরিবর্তিত করে (অভিধানের ক্ষেত্রে) এবং নতুন মানটি দেয়, যা পাইথনের অন্তর্নির্মিত সংগ্রহ পদ্ধতির সাথে অসামঞ্জস্যপূর্ণ হয় যা বর্তমান বস্তুকে রূপান্তর করে বা একটি নতুন ফিরিয়ে দেয়, তবে উভয়ই নয়।
মার্ক আমেরিকা

1

আমার কাছে একটি স্ট্রিং হিসাবে জেএসওন ডিক ছিল। কীগুলি এবং মানগুলি নিম্নোক্ত উদাহরণের মতো ইউনিকোড অবজেক্ট ছিল:

myStringDict = "{u'key':u'value'}"

আমি byteifyস্ট্রিংটিকে কোনও dictবস্তুতে রূপান্তর করে উপরে প্রস্তাবিত ফাংশনটি ব্যবহার করতে পারি ast.literal_eval(myStringDict)


আপনি যে উদাহরণ দিয়েছেন তা JSON এর উদাহরণ নয়। {u'key':u'value'}JSON নয়।
মার্ক আমেরিকা

2
আমি পুরোপুরি জানি এটি জেএসএন নয়। আমার অজগর স্ক্রিপ্টে এটি কোনও বাহ্যিক উত্স থেকে পার্স করা হয়েছিল। এটি যদি নীচের উদাহরণে সরাসরি জেএসওন হিসাবে থাকে তবে সমাধান হিসাবে চিহ্নিত বাইটায় ফাংশনের দরকার পড়েনি: {"ফার্স্টনাম": "জন", "লাস্টনাম": "ডো"}} ভোট দেওয়ার আগে উত্তরগুলি পড়লে এটি দুর্দান্ত হবে। ধন্যবাদ।
নারকো

1

পাইথন 2 এবং 3 হুক ব্যবহার করে সহায়তা করুন ( https://stackoverflow.com/a/33571117/558397 থেকে )

import requests
import six
from six import iteritems

requests.packages.urllib3.disable_warnings()  # @UndefinedVariable
r = requests.get("http://echo.jsontest.com/key/value/one/two/three", verify=False)

def _byteify(data):
    # if this is a unicode string, return its string representation
    if isinstance(data, six.string_types):
        return str(data.encode('utf-8').decode())

    # if this is a list of values, return list of byteified values
    if isinstance(data, list):
        return [ _byteify(item) 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):
        return {
            _byteify(key): _byteify(value) for key, value in iteritems(data)
        }
    # if it's anything else, return it in its original form
    return data

w = r.json(object_hook=_byteify)
print(w)

রিটার্নস:

 {'three': '', 'key': 'value', 'one': 'two'}

0

এটি গেমের দেরীতে, তবে আমি এই পুনরাবৃত্তকারী কাস্টারটি তৈরি করেছি। এটি আমার প্রয়োজনের জন্য কাজ করে এবং আমি মনে করি এটি তুলনামূলকভাবে সম্পূর্ণ। এটি আপনাকে সাহায্য করতে পারে।

def _parseJSON(self, obj):
    newobj = {}

    for key, value in obj.iteritems():
        key = str(key)

        if isinstance(value, dict):
            newobj[key] = self._parseJSON(value)
        elif isinstance(value, list):
            if key not in newobj:
                newobj[key] = []
                for i in value:
                    newobj[key].append(self._parseJSON(i))
        elif isinstance(value, unicode):
            val = str(value)
            if val.isdigit():
                val = int(val)
            else:
                try:
                    val = float(val)
                except ValueError:
                    val = str(val)
            newobj[key] = val

    return newobj

কেবল এটির মতো একটি JSON অবজেক্টটি পাস করুন:

obj = json.loads(content, parse_float=float, parse_int=int)
obj = _parseJSON(obj)

আমার কাছে এটি কোনও শ্রেণীর ব্যক্তিগত সদস্য হিসাবে রয়েছে, তবে আপনি উপযুক্ত হিসাবে পদ্ধতিটি পুনর্নির্মাণ করতে পারেন।


আমি এমন একটি সমস্যায় পড়েছি যেখানে আমি জেএসএনকে বিশ্লেষণ করার চেষ্টা করছি এবং ফলস্বরূপ ম্যাপিংকে কোনও ফাংশনে ** কোয়ার্গ্স হিসাবে পাস করার চেষ্টা করছি। দেখে মনে হচ্ছে ফাংশন প্যারামিটারের নামগুলি ইউনিকোড হতে পারে না, তাই আপনার _ পার্সজেএসএন ফাংশন দুর্দান্ত। যদি আরও সহজ উপায় থাকে তবে কেউ আমাকে জানান।
নিল স্ট্যুবলেন

1
এই কোডটিতে একটি সমস্যা রয়েছে - আপনি তালিকার অংশে একটি পুনরাবৃত্ত কল করেন যা তালিকার উপাদানগুলি নিজেরাই অভিধান না থাকলে ব্যর্থ হতে চলেছে।
I82Much

@ I82Much দ্বারা বর্ণিত বাগের পাশাপাশি এটিরও খারাপ নামকরণ করা হয়েছে (এটি আসলে JSON কে বিশ্লেষণ করে না; json.loadsপ্রথমে একটি কল প্রয়োজন হয়), নির্বিচারে বিনা ব্যাখ্যা ছাড়াই স্ট্রিংগুলিকে ইন্টিতে রূপান্তরিত করার চেষ্টা করে, এবং অনুলিপি-এবং- পেস্ট প্রস্তুত।
মার্ক আমেরি

0

আমি যখন ওয়েসন বস্তুটি নিজেই একটি অ্যারে (আমার ব্যবহারের ক্ষেত্রে) হয় তখন এমন কেসগুলি পরিচালনা করতে ওয়েলসের _ পার্স_জসন () পুনরায় লিখেছিলাম।

def _parseJSON(self, obj):
    if isinstance(obj, dict):
        newobj = {}
        for key, value in obj.iteritems():
            key = str(key)
            newobj[key] = self._parseJSON(value)
    elif isinstance(obj, list):
        newobj = []
        for value in obj:
            newobj.append(self._parseJSON(value))
    elif isinstance(obj, unicode):
        newobj = str(obj)
    else:
        newobj = obj
    return newobj

0

এখানে সিটিতে লিখিত একটি পুনরাবৃত্তির এনকোডার রয়েছে: https://github.com/axiros/nested_encode

Json.loads এর তুলনায় প্রায় 10% "গড়" কাঠামোর জন্য ওভারহেডের পারফরম্যান্স।

python speed.py                                                                                            
  json loads            [0.16sec]: {u'a': [{u'b': [[1, 2, [u'\xd6ster..
  json loads + encoding [0.18sec]: {'a': [{'b': [[1, 2, ['\xc3\x96ster.
  time overhead in percent: 9%

এই পরীক্ষামূলক কাঠামো ব্যবহার করে:

import json, nested_encode, time

s = """
{
  "firstName": "Jos\\u0301",
  "lastName": "Smith",
  "isAlive": true,
  "age": 25,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "\\u00d6sterreich",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
  ],
  "children": [],
  "spouse": null,
  "a": [{"b": [[1, 2, ["\\u00d6sterreich"]]]}]
}
"""


t1 = time.time()
for i in xrange(10000):
    u = json.loads(s)
dt_json = time.time() - t1

t1 = time.time()
for i in xrange(10000):
    b = nested_encode.encode_nested(json.loads(s))
dt_json_enc = time.time() - t1

print "json loads            [%.2fsec]: %s..." % (dt_json, str(u)[:20])
print "json loads + encoding [%.2fsec]: %s..." % (dt_json_enc, str(b)[:20])

print "time overhead in percent: %i%%"  % (100 * (dt_json_enc - dt_json)/dt_json)

0

পাইথন 3.6 দিয়ে, কখনও কখনও আমি এখনও এই সমস্যার মধ্যে চলে যাই। উদাহরণস্বরূপ, একটি REST এপিআইয়ের কাছ থেকে প্রতিক্রিয়া পাওয়ার সময় এবং জেএসএনে প্রতিক্রিয়া পাঠ্য লোড করার সময় আমি এখনও ইউনিকোড স্ট্রিংগুলি পাই। Json.dumps () ব্যবহার করে একটি সাধারণ সমাধান খুঁজে পেয়েছে।

response_message = json.loads(json.dumps(response.text))
print(response_message)

-1

আমিও এই সমস্যায় পড়েছি এবং জেএসওনের সাথে ডিল করার পরে আমি একটি ছোট লুপ নিয়ে এসেছি যা ইউনিকোড কীগুলিকে স্ট্রিংয়ে রূপান্তর করে। ( simplejsonGAE এ স্ট্রিং কীগুলি ফেরত দেয় না))

obj জেএসওএন থেকে ডিকোড করা অবজেক্টটি কী:

if NAME_CLASS_MAP.has_key(cls):
    kwargs = {}
    for i in obj.keys():
        kwargs[str(i)] = obj[i]
    o = NAME_CLASS_MAP[cls](**kwargs)
    o.save()

kwargsআমি যা জিএই অ্যাপ্লিকেশনটির কনস্ট্রাক্টরকে পাস করি (যা unicodeকীগুলি পছন্দ করে না**kwargs )

ওয়েলসের সমাধানের মতো শক্তিশালী নয়, তবে অনেক ছোট।


-1

আমি থেকে কোড অভিযোজিত থাকেন উত্তর এর মার্ক এ Amery বিশেষ করে অনুক্রমে পরিত্রাণ পেতে,isinstance হাঁস-টাইপিং অনুকূল জন্য।

এনকোডিংটি ম্যানুয়ালি করা হয় এবং ensure_asciiঅক্ষম করা হয়। অজগর ডকস json.dumpবলে যে

যদি নিশ্চিত_এএসসিআইটি সত্য (ডিফল্ট) হয় তবে আউটপুটে সমস্ত নন-এএসসিআইআই অক্ষরগুলি \ uXXXX সিকোয়েন্সগুলি সহ পালিয়ে যায়

দাবি অস্বীকার: ডক্টরেটে আমি হাঙ্গেরিয়ান ভাষা ব্যবহার করেছি। কিছু উল্লেখযোগ্য হাঙ্গেরিয়ান সম্পর্কিত চরিত্রের এনকোডিংগুলি হ'ল: cp852আইবিএম / ইএম এনকোডিং যেমন eg ডস (কখনও কখনও ascii হিসাবে উল্লেখ করা হয় , ভুলভাবে আমি মনে করি, এটি কোডপেজ সেটিং এর উপর নির্ভরশীল ), cp1250ব্যবহৃত উদাহরণস্বরূপ। উইন্ডোজে (কখনও কখনও স্থানীয় অ্যাসি হিসাবে পরিচিত , স্থানীয় সেটিংসের উপর নির্ভরশীল) এবং iso-8859-2কখনও কখনও HTTP সার্ভারে ব্যবহৃত হয়। পরীক্ষার পাঠ্যটি কোলতাই লাসলির (স্থানীয় ব্যক্তিগত নাম ফর্ম) Tüskéshátú kígyóbűvölőদ্বারা দায়ী এবং উইকিপিডিয়া থেকে এসেছে ।

# coding: utf-8
"""
This file should be encoded correctly with utf-8.
"""
import json

def encode_items(input, encoding='utf-8'):
    u"""original from: https://stackoverflow.com/a/13101776/611007
    adapted by SO/u/611007 (20150623)
    >>> 
    >>> ## run this with `python -m doctest <this file>.py` from command line
    >>> 
    >>> txt = u"Tüskéshátú kígyóbűvölő"
    >>> txt2 = u"T\\u00fcsk\\u00e9sh\\u00e1t\\u00fa k\\u00edgy\\u00f3b\\u0171v\\u00f6l\\u0151"
    >>> txt3 = u"uúuutifu"
    >>> txt4 = b'u\\xfauutifu'
    >>> # txt4 shouldn't be 'u\\xc3\\xbauutifu', string content needs double backslash for doctest:
    >>> assert u'\\u0102' not in b'u\\xfauutifu'.decode('cp1250')
    >>> txt4u = txt4.decode('cp1250')
    >>> assert txt4u == u'u\\xfauutifu', repr(txt4u)
    >>> txt5 = b"u\\xc3\\xbauutifu"
    >>> txt5u = txt5.decode('utf-8')
    >>> txt6 = u"u\\u251c\\u2551uutifu"
    >>> there_and_back_again = lambda t: encode_items(t, encoding='utf-8').decode('utf-8')
    >>> assert txt == there_and_back_again(txt)
    >>> assert txt == there_and_back_again(txt2)
    >>> assert txt3 == there_and_back_again(txt3)
    >>> assert txt3.encode('cp852') == there_and_back_again(txt4u).encode('cp852')
    >>> assert txt3 == txt4u,(txt3,txt4u)
    >>> assert txt3 == there_and_back_again(txt5)
    >>> assert txt3 == there_and_back_again(txt5u)
    >>> assert txt3 == there_and_back_again(txt4u)
    >>> assert txt3.encode('cp1250') == encode_items(txt4, encoding='utf-8')
    >>> assert txt3.encode('utf-8') == encode_items(txt5, encoding='utf-8')
    >>> assert txt2.encode('utf-8') == encode_items(txt, encoding='utf-8')
    >>> assert {'a':txt2.encode('utf-8')} == encode_items({'a':txt}, encoding='utf-8')
    >>> assert [txt2.encode('utf-8')] == encode_items([txt], encoding='utf-8')
    >>> assert [[txt2.encode('utf-8')]] == encode_items([[txt]], encoding='utf-8')
    >>> assert [{'a':txt2.encode('utf-8')}] == encode_items([{'a':txt}], encoding='utf-8')
    >>> assert {'b':{'a':txt2.encode('utf-8')}} == encode_items({'b':{'a':txt}}, encoding='utf-8')
    """
    try:
        input.iteritems
        return {encode_items(k): encode_items(v) for (k,v) in input.iteritems()}
    except AttributeError:
        if isinstance(input, unicode):
            return input.encode(encoding)
        elif isinstance(input, str):
            return input
        try:
            iter(input)
            return [encode_items(e) for e in input]
        except TypeError:
            return input

def alt_dumps(obj, **kwargs):
    """
    >>> alt_dumps({'a': u"T\\u00fcsk\\u00e9sh\\u00e1t\\u00fa k\\u00edgy\\u00f3b\\u0171v\\u00f6l\\u0151"})
    '{"a": "T\\xc3\\xbcsk\\xc3\\xa9sh\\xc3\\xa1t\\xc3\\xba k\\xc3\\xadgy\\xc3\\xb3b\\xc5\\xb1v\\xc3\\xb6l\\xc5\\x91"}'
    """
    if 'ensure_ascii' in kwargs:
        del kwargs['ensure_ascii']
    return json.dumps(encode_items(obj), ensure_ascii=False, **kwargs)

আমিও হাইলাইট করতে চাই উত্তর এর Jarret হার্ডি যা রেফারেন্স তাদেরকে JSON বৈশিষ্ট , মূল্য উদ্ধৃতি:

একটি স্ট্রিং শূন্য বা আরও ইউনিকোড অক্ষরের সংগ্রহ

আমার ব্যবহারের ক্ষেত্রে আমার সাথে জসন ফাইল ছিল। এগুলি utf-8এনকোড করা ফাইল।ensure_asciiসঠিকভাবে পলায়নের ফলাফল কিন্তু খুব পঠনযোগ্য জসন ফাইল নয়, এ কারণেই আমি আমার প্রয়োজন অনুসারে মার্ক আমেরির উত্তরটি মানিয়ে নিয়েছি।

ডক্টেস্টটি বিশেষভাবে চিন্তাশীল নয় তবে আমি কোডটি এই আশায় ভাগ করছি যে এটি কারওর জন্য কার্যকর হবে useful


আমি নিশ্চিত না আমি এখানে হাঁসের টাইপিংয়ের সুবিধা কী দেখছি? আমরা জানি যেগুলি থেকে ফিরে সংগ্রহগুলি json.loadsতালিকাগুলি বা ডিক্ট হতে চলেছে, কিছু ব্যবহারকারীর দ্বারা সংজ্ঞায়িত বা লাইব্রেরি-সংজ্ঞায়িত প্রকার নয় যা তাদের পদ্ধতি এবং যাদু পদ্ধতি প্রয়োগ করে, তবে কেন কেবল একটি isinstanceপরীক্ষা করা হবে না? অস্তিত্বের অস্তিত্ব পরীক্ষা করার চেয়ে বোঝা কি সহজ নয় iteritemsবা iterবস্তুকে আর্গুমেন্ট হিসাবে গ্রহণ করবে কিনা ?
মার্ক আমেরিকা

@ মার্কআমেরি এটি ডাম্প সম্পর্কে, বোঝা নয়। যদি আপনি ডাম্প করার জন্য ডেটা তৈরি করেন - এটি লোড করার বিপরীতে - আপনি এটি নিশ্চিত কি করতে পারবেন না। ধারণাটি কোডের যে কোনও জায়গা থেকে আসা উচিত।
n611x007

-2

এই মত একটি অনুরূপ প্রশ্নের এই উত্তর যাচাই করে দেখুন

ইউ-উপসর্গটির অর্থ কেবল আপনার একটি ইউনিকোড স্ট্রিং রয়েছে। আপনি যখন সত্যিই স্ট্রিংটি ব্যবহার করবেন তখন এটি আপনার ডেটাতে উপস্থিত হবে না। মুদ্রিত আউটপুট দ্বারা নিক্ষেপ করবেন না।

উদাহরণস্বরূপ, এটি চেষ্টা করুন:

print mail_accounts[0]["i"]

আপনি একটি ইউ দেখতে পাবেন না।


সত্য নয় যদি উদাহরণস্বরূপ, আপনি পাই 2-তে কোনও ইউনিকোড স্ট্রিংযুক্ত কিছু ফর্ম্যাট করতে চান। যেমন '{}'.format({u'x' : u'y'})এখনও ইউ এর অন্তর্ভুক্ত।
পোনকডুডল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.