আমি কীভাবে পাইথনের কোনও ফাইল / স্ট্রিম থেকে অলসভাবে একাধিক জেএসওএন মানগুলি পড়তে পারি?


104

আমি পাইথনের একটি ফাইল / স্ট্রিম থেকে একাধিকবার JSON অবজেক্টগুলি পড়তে চাই। দুর্ভাগ্যক্রমে json.load()কেবল .read()ফাইলের শেষ অবধি; এটি কোনও একক বস্তু পড়ার জন্য বা অবজেক্টগুলির উপর অলসভাবে পুনরাবৃত্তি করার কোনও উপায় বলে মনে হচ্ছে না।

এই কাজ করতে কোন উপায় আছে কি? স্ট্যান্ডার্ড লাইব্রেরিটি ব্যবহার করা আদর্শ হবে তবে তৃতীয় পক্ষের লাইব্রেরি থাকলে আমি তার পরিবর্তে এটি ব্যবহার করব।

এই মুহুর্তে আমি প্রতিটি বস্তুকে পৃথক লাইনে json.loads(f.readline())রেখেছি এবং ব্যবহার করছি , তবে আমি সত্যিই এটি করার দরকার নেই বলে পছন্দ করব।

উদাহরণ ব্যবহার

example.py

import my_json as json
import sys

for o in json.iterload(sys.stdin):
    print("Working on a", type(o))

in.txt

{"foo": ["bar", "baz"]} 1 2 [] 4 5 6

উদাহরণ সেশন

$ python3.2 example.py < in.txt
Working on a dict
Working on a int
Working on a int
Working on a list
Working on a int
Working on a int
Working on a int

দয়া করে নেস্টেড অবজেক্টস থেকে আপনি যে আচরণটি পছন্দ করতে চান তার একটি উদাহরণ যোগ করতে পারেন?
টিম ম্যাকনামারা

@ টিমএমসিএনমারা: নেস্টেড বস্তুর আচরণ পরিবর্তন করা উচিত নয়। যাইহোক, একবার আমরা প্রথম শীর্ষ-স্তরের অবজেক্টের শেষে পৌঁছেছি ( {"foo": ["bar", "baz"]}আমার উদাহরণে), এটি হওয়া উচিত yieldএবং তারপরে পরবর্তীটিতে ( 1) চালিয়ে যাওয়া উচিত ।
জেরেমি

4
কেন "জসন লাইন" এড়ানো? জেসসনে কোনও বস্তুর সিরিয়ালাইজ করা সর্বদা সম্ভব যে '\n'এর জসন উপস্থাপনায় এর কোনও (একক নিউলাইন নয়, দুটি অক্ষর) নেই কারণ জেসন স্ট্রিংয়ের ভিতরে '\n'অবশ্যই পালাতে হবে এবং তাই '\n'কেবলমাত্র ফর্ম্যাটিংয়ের জন্যই এটি ব্যবহার করা যেতে পারে, আমি বিশ্বাস করি json.dumps()না ' '\n'ডিফল্টরূপে পরিচয় করিয়ে দিন । সাবধান হোন যে ইউনিকোড নিউলাইনগুলি যেমন ইউ + 0085 জেসন স্ট্রিংয়ের মধ্যে আনসকেপড থাকতে পারে।
jfs

4
এই ক্ষেত্রে আইজসন গ্রন্থাগারটি কার্যকর হতে পারে। pypi.python.org/pypi/ijson github.com/isagalaev/ijson
বোরিস চেরভেনকভ

4
শিরোনামটি হওয়া উচিত নয় "পাইথনের কোনও ফাইল / স্ট্রিম থেকে আমি কীভাবে অলসভাবে একাধিক জেএসওএন মানগুলি পড়তে পারি ?" যেহেতু কোনও বস্তু একটি মান যেমন একটি জসন ইন, স্ট্রিং ইত্যাদির মতো হয় তবে বিপরীতটি সত্য হয় না?
hetepepphaan

উত্তর:


21

এখানে একটি অনেক, অনেক সহজ সমাধান। গোপনীয়তা হ'ল চেষ্টা করা, ব্যর্থ হওয়া এবং তথ্যকে সঠিকভাবে পার্স করা ব্যতিক্রম। একমাত্র সীমাবদ্ধতা ফাইলটি সন্ধানযোগ্য হতে হবে।

def stream_read_json(fn):
    import json
    start_pos = 0
    with open(fn, 'r') as f:
        while True:
            try:
                obj = json.load(f)
                yield obj
                return
            except json.JSONDecodeError as e:
                f.seek(start_pos)
                json_str = f.read(e.pos)
                obj = json.loads(json_str)
                start_pos += e.pos
                yield obj

সম্পাদনা: সবেমাত্র লক্ষ্য করেছেন যে এটি কেবল পাইথন> = 3.5 এর জন্য কাজ করবে। পূর্বের জন্য, ব্যর্থতাগুলি একটি মান মূল্য দেয়, এবং আপনাকে স্ট্রিং থেকে অবস্থানটি বিশ্লেষণ করতে হবে, যেমন

def stream_read_json(fn):
    import json
    import re
    start_pos = 0
    with open(fn, 'r') as f:
        while True:
            try:
                obj = json.load(f)
                yield obj
                return
            except ValueError as e:
                f.seek(start_pos)
                end_pos = int(re.match('Extra data: line \d+ column \d+ .*\(char (\d+).*\)',
                                    e.args[0]).groups()[0])
                json_str = f.read(end_pos)
                obj = json.loads(json_str)
                start_pos += end_pos
                yield obj

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

এটি reকাজ করবে না - ব্যাকস্ল্যাশগুলি পালানোর প্রয়োজন। একটি কাঁচা স্ট্রিং বিবেচনা করুন r'...'
টম সুইরিলি

4
আমার নিজের কাজের জন্য এটি আমার প্রয়োজন ছিল, তাই II কিছু কৌশল নিয়ে আপনার কৌশলটি কম-বেশি ব্যবহার করে এটি করার জন্য একটি অল্প অজগর গ্রন্থাগার তৈরি করেছিল এবং এটি এখানে রয়েছে: পাইপি.পাইথন.আর.পিপি
টম সোয়ারলি

4
আপনি যদি তার ujsonপরিবর্তে ব্যবহার করেন তবে jsonএকটি বিশাল
স্পিডআপ

40

জেএসএন সাধারণত এই ধরণের বর্ধিত ব্যবহারের পক্ষে খুব ভাল নয়; একাধিক অবজেক্টকে সিরিয়াল করার কোনও আদর্শ উপায় নেই যাতে পুরো লটটি পার্সিং না করেই তারা একবারে সহজেই লোড করা যায়।

আপনি যে লাইনের সমাধানটি ব্যবহার করছেন তা অন্য কোথাও দেখা যায়। থেরাপি এটিকে 'জেএসএন লাইনস' বলে ডাকে:

আপনি এটি পাইথোনিকভাবে আরও কিছুটা করতে পারেন:

for jsonline in f:
    yield json.loads(jsonline)   # or do the processing in this loop

আমি মনে করি এটি সর্বোত্তম উপায় সম্পর্কে - এটি কোনও তৃতীয় পক্ষের লাইব্রেরিতে নির্ভর করে না এবং কী চলছে তা বোঝা সহজ। আমি এটি নিজের কয়েকটি কোডেও ব্যবহার করেছি।


4
পুনরায়: "কোনও মানসম্মত উপায় নেই": আমি সমস্যাটি দেখছি না, সিনট্যাক্সটি মনে হয় আপনার এক-চরিত্রের বাফার যতক্ষণ না একাধিক ক্রমাগত অবজেক্টগুলিকে দ্ব্যর্থহীন করে তুলবে। অন্যান্য ব্যক্তিরা "জেএসওএন লাইনগুলি" ব্যবহার করে বলে চিহ্নিত করার জন্য ধন্যবাদ, আপাতত এটি ব্যবহার করা সম্পর্কে আমার খারাপ লাগছে না।
জেরেমি

31

কিছুটা দেরি হতে পারে তবে আমার এই সঠিক সমস্যাটি ছিল (ভাল, কম বা কম)। এই সমস্যাগুলির জন্য আমার স্ট্যান্ডার্ড সমাধানটি হ'ল কিছু সুপরিচিত মূল বস্তুর উপর কেবলমাত্র একটি রেগেক্স বিভাজন করা, তবে আমার ক্ষেত্রে এটি অসম্ভব ছিল। সাধারণভাবে এটি করার একমাত্র সম্ভাব্য উপায় হ'ল সঠিক টোকেনাইজার প্রয়োগ করা

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

উদাহরণ:

from splitstream import splitfile

for jsonstr in splitfile(sys.stdin, format="json")):
    yield json.loads(jsonstr)

সেটা খুবই ভালো. এটি ভাগ করে নেওয়ার জন্য ধন্যবাদ।
জেরেমি

এটিই এর চূড়ান্ত সমাধান। আমি আশা করি আপনি এটি আপডেট করা চালিয়ে যান।
বার্টভিডস 14:38

এটা সহজভাবে কাজ করে। যেমন একটি দরকারী মডিউল সরবরাহ করার জন্য ধন্যবাদ।
বিনোদ শর্মা

4
আপনি কি একটি সংকলিত .py সংস্করণ আপলোড করতে পারবেন? আমি মডিউলটি তৈরি এবং ইনস্টল করার চেষ্টা করেছি কিন্তু ... এটি পুনরায় সংজ্ঞায়িত ধ্রুবকগুলি এবং এ জাতীয় ত্রুটিগুলির একগুচ্ছ উত্পাদন করে।
স্যারজেমস

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

25

অবশ্যই আপনি এটি করতে পারেন। আপনি কেবল raw_decodeসরাসরি নিতে হবে । এই প্রয়োগটি পুরো ফাইলটিকে মেমরিতে লোড করে এবং সেই স্ট্রিংয়ে চালিত করে (যেমনটি json.loadকরে); আপনার কাছে যদি বড় ফাইল থাকে তবে আপনি এটিকে পরিবর্তন করতে পারবেন কেবল কোনও সমস্যা ছাড়াই প্রয়োজনীয় ফাইল থেকে পড়তে।

import json
from json.decoder import WHITESPACE

def iterload(string_or_fp, cls=json.JSONDecoder, **kwargs):
    if isinstance(string_or_fp, file):
        string = string_or_fp.read()
    else:
        string = str(string_or_fp)

    decoder = cls(**kwargs)
    idx = WHITESPACE.match(string, 0).end()
    while idx < len(string):
        obj, end = decoder.raw_decode(string, idx)
        yield obj
        idx = WHITESPACE.match(string, end).end()

ব্যবহার: আপনি যেমন অনুরোধ করেছিলেন ঠিক তেমনই এটি একটি জেনারেটর।


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

24

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

জেনারেটরদের উদ্ধার!

এই জাতীয় সমস্যার জন্য জেনারেটরগুলির সৌন্দর্য হ'ল আপনি একে অপরের উপরে এটি স্ট্যাক করতে পারেন ধীরে ধীরে অলসতা বজায় রেখে সমস্যার অসুবিধা দূরে সরিয়ে দিতে। আমি জেনারেটর (প্রেরণ ()) এর মধ্যে মানগুলি পাস করার জন্য প্রক্রিয়াটি ব্যবহার করার বিষয়টিও বিবেচনা করেছি তবে ভাগ্যক্রমে আমি এটি ব্যবহার করার দরকার পড়েনি I

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

import re

def streamingfinditer(pat,stream):
  for s in stream:
#    print "Read next line: " + s
    while 1:
      m = re.search(pat,s)
      if not m:
        yield (0,s)
        break
      yield (1,m.group())
      s = re.split(pat,s,1)[1]

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

braces='{}[]'
whitespaceesc=' \t'
bracesesc='\\'+'\\'.join(braces)
balancemap=dict(zip(braces,[1,-1,1,-1]))
bracespat='['+bracesesc+']'
nobracespat='[^'+bracesesc+']*'
untilbracespat=nobracespat+bracespat

def simpleorcompoundobjects(stream):
  obj = ""
  unbalanced = 0
  for (c,m) in streamingfinditer(re.compile(untilbracespat),stream):
    if (c == 0): # remainder of line returned, nothing interesting
      if (unbalanced == 0):
        yield (0,m)
      else:
        obj += m
    if (c == 1): # match returned
      if (unbalanced == 0):
        yield (0,m[:-1])
        obj += m[-1]
      else:
        obj += m
      unbalanced += balancemap[m[-1]]
      if (unbalanced == 0):
        yield (1,obj)
        obj="" 

এটি নীচে tuples ফেরত:

(0,"String of simple non-braced objects easy to parse")
(1,"{ 'Compound' : 'objects' }")

মূলত এটি করা বাজে অংশ part আমরা এখন ঠিক দেখতে পার্সিংয়ের চূড়ান্ত স্তরের পার্সিংটি করতে হবে। উদাহরণস্বরূপ আমরা জেরেমি রোমানের ইটারলোড ফাংশন (ধন্যবাদ!) ব্যবহার করতে পারি একটি লাইনের জন্য পার্সিং করতে:

def streamingiterload(stream):
  for c,o in simpleorcompoundobjects(stream):
    for x in iterload(o):
      yield x 

এটা পরীক্ষা করো:

of = open("test.json","w") 
of.write("""[ "hello" ] { "goodbye" : 1 } 1 2 {
} 2
9 78
 4 5 { "animals" : [ "dog" , "lots of mice" ,
 "cat" ] }
""")
of.close()
// open & stream the json
f = open("test.json","r")
for o in streamingiterload(f.readlines()):
  print o
f.close()

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

[u'hello']
{u'goodbye': 1}
1
2
{}
2
9
78
4
5
{u'animals': [u'dog', u'lots of mice', u'cat']}

এটি সমস্ত পরিস্থিতিতে কাজ করবে না। jsonলাইব্রেরি বাস্তবায়নের কারণে , নিজেকে পার্সার সংশোধন না করে পুরোপুরি সঠিকভাবে কাজ করা অসম্ভব


8
আপনি যদি এটি সঠিকভাবে করতে চান, আপনার স্ট্রিংগুলির মধ্যেও বন্ধনী এবং বন্ধনীগুলির জন্য নজর রাখা দরকার। এবং তারপরে পালানো উদ্ধৃতিগুলির জন্যও নজর রাখুন। আপনি এটি জানার আগে, "প্রিপার্সার" একটি সম্পূর্ণ জেএসএন পার্সার হিসাবে প্রায় জটিল হয়ে উঠবে।
পেটর ভিক্টরিন

ধন্যবাদ জেরেমি এটি একটি প্রশ্নের চ্যালেঞ্জ ছিল! হ্যাঁ পেটর - আপনি অবশ্যই একদম ঠিক আছেন :)
বেনিডিক্ট

4
সুন্দরভাবে সম্পন্ন. অক্ষরগুলি JSON স্ট্রিংগুলিতে পছন্দ হয় "}"এবং "]"ঘটে তবে এটি কি সঠিকভাবে আচরণ করবে ? আমি মনে করি এটি রেগেক্সের সাথে পার্স করার একটি সাধারণ সীমাবদ্ধতা।
থমাস কে

4
যখন চারপাশে হাঁসফাঁস করলাম আমি দেখতে পেলাম মূল পার্সিং ফাংশনটি এমনভাবে তৈরি করা হয়েছে যাতে এটি অলসভাবে সঠিকভাবে ব্যবহার করা অসম্ভব , সুতরাং আপনি নিজের দ্বারা সম্পূর্ণ পার্সার প্রয়োগ না করে আপনি একটি নিখুঁত ফলাফল পেতে যাচ্ছেন না। এই উত্তরটি বেশ কয়েকটি দরকারী প্রাসঙ্গিক জিনিস প্রদর্শন করে এবং সাধারণ কেসগুলি সুন্দরভাবে পরিচালনা করে।
জেরেমি

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

10

আমি বিশ্বাস করি এটি করার আরও ভাল উপায় হ'ল একটি রাষ্ট্রীয় মেশিন ব্যবহার করা। নীচে পাইথন 3 এর লিঙ্কে নোডজেএস কোড রূপান্তর করে আমি একটি নমুনা কোড দিয়ে কাজ করেছি (কেবল পাইথন 3 এ উপলব্ধ ননলোকাল কীওয়ার্ড ব্যবহৃত হয়েছে, কোডটি পাইথন 2 তে কাজ করবে না)

সম্পাদনা -১: পাইথন 2 এর সাথে আপডেট হয়েছে এবং কোডটি উপযুক্ত made

সম্পাদনা -২: আপডেট করা হয়েছে এবং পাশাপাশি একটি পাইথন 3 সংস্করণ যুক্ত করেছে

https://gist.github.com/creationix/5992451

পাইথন 3 কেবল সংস্করণ

# A streaming byte oriented JSON parser.  Feed it a single byte at a time and
# it will emit complete objects as it comes across them.  Whitespace within and
# between objects is ignored.  This means it can parse newline delimited JSON.
import math


def json_machine(emit, next_func=None):
    def _value(byte_data):
        if not byte_data:
            return

        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _value  # Ignore whitespace

        if byte_data == 0x22:  # "
            return string_machine(on_value)

        if byte_data == 0x2d or (0x30 <= byte_data < 0x40):  # - or 0-9
            return number_machine(byte_data, on_number)

        if byte_data == 0x7b:  #:
            return object_machine(on_value)

        if byte_data == 0x5b:  # [
            return array_machine(on_value)

        if byte_data == 0x74:  # t
            return constant_machine(TRUE, True, on_value)

        if byte_data == 0x66:  # f
            return constant_machine(FALSE, False, on_value)

        if byte_data == 0x6e:  # n
            return constant_machine(NULL, None, on_value)

        if next_func == _value:
            raise Exception("Unexpected 0x" + str(byte_data))

        return next_func(byte_data)

    def on_value(value):
        emit(value)
        return next_func

    def on_number(number, byte):
        emit(number)
        return _value(byte)

    next_func = next_func or _value
    return _value


TRUE = [0x72, 0x75, 0x65]
FALSE = [0x61, 0x6c, 0x73, 0x65]
NULL = [0x75, 0x6c, 0x6c]


def constant_machine(bytes_data, value, emit):
    i = 0
    length = len(bytes_data)

    def _constant(byte_data):
        nonlocal i
        if byte_data != bytes_data[i]:
            i += 1
            raise Exception("Unexpected 0x" + str(byte_data))

        i += 1
        if i < length:
            return _constant
        return emit(value)

    return _constant


def string_machine(emit):
    string = ""

    def _string(byte_data):
        nonlocal string

        if byte_data == 0x22:  # "
            return emit(string)

        if byte_data == 0x5c:  # \
            return _escaped_string

        if byte_data & 0x80:  # UTF-8 handling
            return utf8_machine(byte_data, on_char_code)

        if byte_data < 0x20:  # ASCII control character
            raise Exception("Unexpected control character: 0x" + str(byte_data))

        string += chr(byte_data)
        return _string

    def _escaped_string(byte_data):
        nonlocal string

        if byte_data == 0x22 or byte_data == 0x5c or byte_data == 0x2f:  # " \ /
            string += chr(byte_data)
            return _string

        if byte_data == 0x62:  # b
            string += "\b"
            return _string

        if byte_data == 0x66:  # f
            string += "\f"
            return _string

        if byte_data == 0x6e:  # n
            string += "\n"
            return _string

        if byte_data == 0x72:  # r
            string += "\r"
            return _string

        if byte_data == 0x74:  # t
            string += "\t"
            return _string

        if byte_data == 0x75:  # u
            return hex_machine(on_char_code)

    def on_char_code(char_code):
        nonlocal string
        string += chr(char_code)
        return _string

    return _string


# Nestable state machine for UTF-8 Decoding.
def utf8_machine(byte_data, emit):
    left = 0
    num = 0

    def _utf8(byte_data):
        nonlocal num, left
        if (byte_data & 0xc0) != 0x80:
            raise Exception("Invalid byte in UTF-8 character: 0x" + byte_data.toString(16))

        left = left - 1

        num |= (byte_data & 0x3f) << (left * 6)
        if left:
            return _utf8
        return emit(num)

    if 0xc0 <= byte_data < 0xe0:  # 2-byte UTF-8 Character
        left = 1
        num = (byte_data & 0x1f) << 6
        return _utf8

    if 0xe0 <= byte_data < 0xf0:  # 3-byte UTF-8 Character
        left = 2
        num = (byte_data & 0xf) << 12
        return _utf8

    if 0xf0 <= byte_data < 0xf8:  # 4-byte UTF-8 Character
        left = 3
        num = (byte_data & 0x07) << 18
        return _utf8

    raise Exception("Invalid byte in UTF-8 string: 0x" + str(byte_data))


# Nestable state machine for hex escaped characters
def hex_machine(emit):
    left = 4
    num = 0

    def _hex(byte_data):
        nonlocal num, left

        if 0x30 <= byte_data < 0x40:
            i = byte_data - 0x30
        elif 0x61 <= byte_data <= 0x66:
            i = byte_data - 0x57
        elif 0x41 <= byte_data <= 0x46:
            i = byte_data - 0x37
        else:
            raise Exception("Expected hex char in string hex escape")

        left -= 1
        num |= i << (left * 4)

        if left:
            return _hex
        return emit(num)

    return _hex


def number_machine(byte_data, emit):
    sign = 1
    number = 0
    decimal = 0
    esign = 1
    exponent = 0

    def _mid(byte_data):
        if byte_data == 0x2e:  # .
            return _decimal

        return _later(byte_data)

    def _number(byte_data):
        nonlocal number
        if 0x30 <= byte_data < 0x40:
            number = number * 10 + (byte_data - 0x30)
            return _number

        return _mid(byte_data)

    def _start(byte_data):
        if byte_data == 0x30:
            return _mid

        if 0x30 < byte_data < 0x40:
            return _number(byte_data)

        raise Exception("Invalid number: 0x" + str(byte_data))

    if byte_data == 0x2d:  # -
        sign = -1
        return _start

    def _decimal(byte_data):
        nonlocal decimal
        if 0x30 <= byte_data < 0x40:
            decimal = (decimal + byte_data - 0x30) / 10
            return _decimal

        return _later(byte_data)

    def _later(byte_data):
        if byte_data == 0x45 or byte_data == 0x65:  # E e
            return _esign

        return _done(byte_data)

    def _esign(byte_data):
        nonlocal esign
        if byte_data == 0x2b:  # +
            return _exponent

        if byte_data == 0x2d:  # -
            esign = -1
            return _exponent

        return _exponent(byte_data)

    def _exponent(byte_data):
        nonlocal exponent
        if 0x30 <= byte_data < 0x40:
            exponent = exponent * 10 + (byte_data - 0x30)
            return _exponent

        return _done(byte_data)

    def _done(byte_data):
        value = sign * (number + decimal)
        if exponent:
            value *= math.pow(10, esign * exponent)

        return emit(value, byte_data)

    return _start(byte_data)


def array_machine(emit):
    array_data = []

    def _array(byte_data):
        if byte_data == 0x5d:  # ]
            return emit(array_data)

        return json_machine(on_value, _comma)(byte_data)

    def on_value(value):
        array_data.append(value)

    def _comma(byte_data):
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _comma  # Ignore whitespace

        if byte_data == 0x2c:  # ,
            return json_machine(on_value, _comma)

        if byte_data == 0x5d:  # ]
            return emit(array_data)

        raise Exception("Unexpected byte: 0x" + str(byte_data) + " in array body")

    return _array


def object_machine(emit):
    object_data = {}
    key = None

    def _object(byte_data):
        if byte_data == 0x7d:  #
            return emit(object_data)

        return _key(byte_data)

    def _key(byte_data):
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _object  # Ignore whitespace

        if byte_data == 0x22:
            return string_machine(on_key)

        raise Exception("Unexpected byte: 0x" + str(byte_data))

    def on_key(result):
        nonlocal key
        key = result
        return _colon

    def _colon(byte_data):
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _colon  # Ignore whitespace

        if byte_data == 0x3a:  # :
            return json_machine(on_value, _comma)

        raise Exception("Unexpected byte: 0x" + str(byte_data))

    def on_value(value):
        object_data[key] = value

    def _comma(byte_data):
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _comma  # Ignore whitespace

        if byte_data == 0x2c:  # ,
            return _key

        if byte_data == 0x7d:  #
            return emit(object_data)

        raise Exception("Unexpected byte: 0x" + str(byte_data))

    return _object

পাইথন 2 সামঞ্জস্যপূর্ণ সংস্করণ

# A streaming byte oriented JSON parser.  Feed it a single byte at a time and
# it will emit complete objects as it comes across them.  Whitespace within and
# between objects is ignored.  This means it can parse newline delimited JSON.
import math


def json_machine(emit, next_func=None):
    def _value(byte_data):
        if not byte_data:
            return

        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _value  # Ignore whitespace

        if byte_data == 0x22:  # "
            return string_machine(on_value)

        if byte_data == 0x2d or (0x30 <= byte_data < 0x40):  # - or 0-9
            return number_machine(byte_data, on_number)

        if byte_data == 0x7b:  #:
            return object_machine(on_value)

        if byte_data == 0x5b:  # [
            return array_machine(on_value)

        if byte_data == 0x74:  # t
            return constant_machine(TRUE, True, on_value)

        if byte_data == 0x66:  # f
            return constant_machine(FALSE, False, on_value)

        if byte_data == 0x6e:  # n
            return constant_machine(NULL, None, on_value)

        if next_func == _value:
            raise Exception("Unexpected 0x" + str(byte_data))

        return next_func(byte_data)

    def on_value(value):
        emit(value)
        return next_func

    def on_number(number, byte):
        emit(number)
        return _value(byte)

    next_func = next_func or _value
    return _value


TRUE = [0x72, 0x75, 0x65]
FALSE = [0x61, 0x6c, 0x73, 0x65]
NULL = [0x75, 0x6c, 0x6c]


def constant_machine(bytes_data, value, emit):
    local_data = {"i": 0, "length": len(bytes_data)}

    def _constant(byte_data):
        # nonlocal i, length
        if byte_data != bytes_data[local_data["i"]]:
            local_data["i"] += 1
            raise Exception("Unexpected 0x" + byte_data.toString(16))

        local_data["i"] += 1

        if local_data["i"] < local_data["length"]:
            return _constant
        return emit(value)

    return _constant


def string_machine(emit):
    local_data = {"string": ""}

    def _string(byte_data):
        # nonlocal string

        if byte_data == 0x22:  # "
            return emit(local_data["string"])

        if byte_data == 0x5c:  # \
            return _escaped_string

        if byte_data & 0x80:  # UTF-8 handling
            return utf8_machine(byte_data, on_char_code)

        if byte_data < 0x20:  # ASCII control character
            raise Exception("Unexpected control character: 0x" + byte_data.toString(16))

        local_data["string"] += chr(byte_data)
        return _string

    def _escaped_string(byte_data):
        # nonlocal string

        if byte_data == 0x22 or byte_data == 0x5c or byte_data == 0x2f:  # " \ /
            local_data["string"] += chr(byte_data)
            return _string

        if byte_data == 0x62:  # b
            local_data["string"] += "\b"
            return _string

        if byte_data == 0x66:  # f
            local_data["string"] += "\f"
            return _string

        if byte_data == 0x6e:  # n
            local_data["string"] += "\n"
            return _string

        if byte_data == 0x72:  # r
            local_data["string"] += "\r"
            return _string

        if byte_data == 0x74:  # t
            local_data["string"] += "\t"
            return _string

        if byte_data == 0x75:  # u
            return hex_machine(on_char_code)

    def on_char_code(char_code):
        # nonlocal string
        local_data["string"] += chr(char_code)
        return _string

    return _string


# Nestable state machine for UTF-8 Decoding.
def utf8_machine(byte_data, emit):
    local_data = {"left": 0, "num": 0}

    def _utf8(byte_data):
        # nonlocal num, left
        if (byte_data & 0xc0) != 0x80:
            raise Exception("Invalid byte in UTF-8 character: 0x" + byte_data.toString(16))

        local_data["left"] -= 1

        local_data["num"] |= (byte_data & 0x3f) << (local_data["left"] * 6)
        if local_data["left"]:
            return _utf8
        return emit(local_data["num"])

    if 0xc0 <= byte_data < 0xe0:  # 2-byte UTF-8 Character
        local_data["left"] = 1
        local_data["num"] = (byte_data & 0x1f) << 6
        return _utf8

    if 0xe0 <= byte_data < 0xf0:  # 3-byte UTF-8 Character
        local_data["left"] = 2
        local_data["num"] = (byte_data & 0xf) << 12
        return _utf8

    if 0xf0 <= byte_data < 0xf8:  # 4-byte UTF-8 Character
        local_data["left"] = 3
        local_data["num"] = (byte_data & 0x07) << 18
        return _utf8

    raise Exception("Invalid byte in UTF-8 string: 0x" + str(byte_data))


# Nestable state machine for hex escaped characters
def hex_machine(emit):
    local_data = {"left": 4, "num": 0}

    def _hex(byte_data):
        # nonlocal num, left
        i = 0  # Parse the hex byte
        if 0x30 <= byte_data < 0x40:
            i = byte_data - 0x30
        elif 0x61 <= byte_data <= 0x66:
            i = byte_data - 0x57
        elif 0x41 <= byte_data <= 0x46:
            i = byte_data - 0x37
        else:
            raise Exception("Expected hex char in string hex escape")

        local_data["left"] -= 1
        local_data["num"] |= i << (local_data["left"] * 4)

        if local_data["left"]:
            return _hex
        return emit(local_data["num"])

    return _hex


def number_machine(byte_data, emit):
    local_data = {"sign": 1, "number": 0, "decimal": 0, "esign": 1, "exponent": 0}

    def _mid(byte_data):
        if byte_data == 0x2e:  # .
            return _decimal

        return _later(byte_data)

    def _number(byte_data):
        # nonlocal number
        if 0x30 <= byte_data < 0x40:
            local_data["number"] = local_data["number"] * 10 + (byte_data - 0x30)
            return _number

        return _mid(byte_data)

    def _start(byte_data):
        if byte_data == 0x30:
            return _mid

        if 0x30 < byte_data < 0x40:
            return _number(byte_data)

        raise Exception("Invalid number: 0x" + byte_data.toString(16))

    if byte_data == 0x2d:  # -
        local_data["sign"] = -1
        return _start

    def _decimal(byte_data):
        # nonlocal decimal
        if 0x30 <= byte_data < 0x40:
            local_data["decimal"] = (local_data["decimal"] + byte_data - 0x30) / 10
            return _decimal

        return _later(byte_data)

    def _later(byte_data):
        if byte_data == 0x45 or byte_data == 0x65:  # E e
            return _esign

        return _done(byte_data)

    def _esign(byte_data):
        # nonlocal esign
        if byte_data == 0x2b:  # +
            return _exponent

        if byte_data == 0x2d:  # -
            local_data["esign"] = -1
            return _exponent

        return _exponent(byte_data)

    def _exponent(byte_data):
        # nonlocal exponent
        if 0x30 <= byte_data < 0x40:
            local_data["exponent"] = local_data["exponent"] * 10 + (byte_data - 0x30)
            return _exponent

        return _done(byte_data)

    def _done(byte_data):
        value = local_data["sign"] * (local_data["number"] + local_data["decimal"])
        if local_data["exponent"]:
            value *= math.pow(10, local_data["esign"] * local_data["exponent"])

        return emit(value, byte_data)

    return _start(byte_data)


def array_machine(emit):
    local_data = {"array_data": []}

    def _array(byte_data):
        if byte_data == 0x5d:  # ]
            return emit(local_data["array_data"])

        return json_machine(on_value, _comma)(byte_data)

    def on_value(value):
        # nonlocal array_data
        local_data["array_data"].append(value)

    def _comma(byte_data):
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _comma  # Ignore whitespace

        if byte_data == 0x2c:  # ,
            return json_machine(on_value, _comma)

        if byte_data == 0x5d:  # ]
            return emit(local_data["array_data"])

        raise Exception("Unexpected byte: 0x" + str(byte_data) + " in array body")

    return _array


def object_machine(emit):
    local_data = {"object_data": {}, "key": ""}

    def _object(byte_data):
        # nonlocal object_data, key
        if byte_data == 0x7d:  #
            return emit(local_data["object_data"])

        return _key(byte_data)

    def _key(byte_data):
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _object  # Ignore whitespace

        if byte_data == 0x22:
            return string_machine(on_key)

        raise Exception("Unexpected byte: 0x" + byte_data.toString(16))

    def on_key(result):
        # nonlocal object_data, key
        local_data["key"] = result
        return _colon

    def _colon(byte_data):
        # nonlocal object_data, key
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _colon  # Ignore whitespace

        if byte_data == 0x3a:  # :
            return json_machine(on_value, _comma)

        raise Exception("Unexpected byte: 0x" + str(byte_data))

    def on_value(value):
        # nonlocal object_data, key
        local_data["object_data"][local_data["key"]] = value

    def _comma(byte_data):
        # nonlocal object_data
        if byte_data == 0x09 or byte_data == 0x0a or byte_data == 0x0d or byte_data == 0x20:
            return _comma  # Ignore whitespace

        if byte_data == 0x2c:  # ,
            return _key

        if byte_data == 0x7d:  #
            return emit(local_data["object_data"])

        raise Exception("Unexpected byte: 0x" + str(byte_data))

    return _object

এটি পরীক্ষা করা হচ্ছে

if __name__ == "__main__":
    test_json = """[1,2,"3"] {"name": 
    "tarun"} 1 2 
    3 [{"name":"a", 
    "data": [1,
    null,2]}]
"""
    def found_json(data):
        print(data)

    state = json_machine(found_json)

    for char in test_json:
        state = state(ord(char))

একই আউটপুট হয়

[1, 2, '3']
{'name': 'tarun'}
1
2
3
[{'name': 'a', 'data': [1, None, 2]}]

চমৎকার সমাধান! আমি পরে আরও ঘুরে দেখব তবে এটি খুব আশাব্যঞ্জক। তবে এটির মূল্য কী, তার জন্য আমি পাইথন 3-কেবলমাত্র সংস্করণটিকেই প্রাধান্য দিয়েছি। আপনার সমস্ত স্থানীয় ভেরিয়েবলের জন্য ডিক্ট ব্যবহার করা একদম বিশ্রী এবং আমি অতীতের জন্য পাইথন 2 ছেড়ে খুশি হয়েছি। ;)
জেরেমি

@ জেরেমিব্যাঙ্কস, আপনি কোন সংস্করণটিকে টার্গেট করেছেন তা আমি নিশ্চিতভাবে জানি না। এখন আমি পাইথন 3 কেবলমাত্র সংস্করণ এবং পাই 2 এর সাথে সামঞ্জস্যপূর্ণ একটি যুক্ত করেছি যার উত্তরটিতে পাইথন 2
তরুন লালওয়ানি

@ জেরেমি ব্যাংকস, অনুগ্রহের সাথে মাত্র একদিন বাকি, আশা করি আপনি উত্তরটি পর্যালোচনা করতে এবং প্রতিক্রিয়া জানাতে পারবেন
তরুণ লালওয়ানি

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

4

আমি একটি সমাধান দিতে চাই। মূল চিন্তাটি হ'ল ডিকোড করার "চেষ্টা করুন": যদি এটি ব্যর্থ হয় তবে এটিকে আরও ফিড দিন, না হলে পরবর্তী ডিকোডিং প্রস্তুত করতে অফসেট তথ্য ব্যবহার করুন।

তবে বর্তমান জসন মডিউল স্পেসিকে স্ট্রিংয়ের শিরোনামে ডিকোড করার জন্য সহ্য করতে পারে না, তাই আমাকে সেগুলি সরিয়ে ফেলতে হবে।

import sys
import json

def iterload(file):
    buffer = ""
    dec = json.JSONDecoder()
    for line in file:         
        buffer = buffer.strip(" \n\r\t") + line.strip(" \n\r\t")
        while(True):
            try:
                r = dec.raw_decode(buffer)
            except:
                break
            yield r[0]
            buffer = buffer[r[1]:].strip(" \n\r\t")


for o in iterload(sys.stdin):
    print("Working on a", type(o),  o)

========================= আমি বেশ কয়েকটি টিএসটি ফাইলের জন্য পরীক্ষা করেছি এবং এটি দুর্দান্ত কাজ করে। (in1.txt)

{"foo": ["bar", "baz"]
}
 1 2 [
  ]  4
{"foo1": ["bar1", {"foo2":{"A":1, "B":3}, "DDD":4}]
}
 5   6

(in2.txt)

{"foo"
: ["bar",
  "baz"]
  } 
1 2 [
] 4 5 6

(in.txt, আপনার প্রাথমিক)

{"foo": ["bar", "baz"]} 1 2 [] 4 5 6

(বেনিডিক্টের টেস্টকেসের জন্য আউটপুট)

python test.py < in.txt
('Working on a', <type 'list'>, [u'hello'])
('Working on a', <type 'dict'>, {u'goodbye': 1})
('Working on a', <type 'int'>, 1)
('Working on a', <type 'int'>, 2)
('Working on a', <type 'dict'>, {})
('Working on a', <type 'int'>, 2)
('Working on a', <type 'int'>, 9)
('Working on a', <type 'int'>, 78)
('Working on a', <type 'int'>, 4)
('Working on a', <type 'int'>, 5)
('Working on a', <type 'dict'>, {u'animals': [u'dog', u'lots of mice', u'cat']})

3

এখানে আমার:

import simplejson as json
from simplejson import JSONDecodeError
class StreamJsonListLoader():
    """
    When you have a big JSON file containint a list, such as

    [{
        ...
    },
    {
        ...
    },
    {
        ...
    },
    ...
    ]

    And it's too big to be practically loaded into memory and parsed by json.load,
    This class comes to the rescue. It lets you lazy-load the large json list.
    """

    def __init__(self, filename_or_stream):
        if type(filename_or_stream) == str:
            self.stream = open(filename_or_stream)
        else:
            self.stream = filename_or_stream

        if not self.stream.read(1) == '[':
            raise NotImplementedError('Only JSON-streams of lists (that start with a [) are supported.')

    def __iter__(self):
        return self

    def next(self):
        read_buffer = self.stream.read(1)
        while True:
            try:
                json_obj = json.loads(read_buffer)

                if not self.stream.read(1) in [',',']']:
                    raise Exception('JSON seems to be malformed: object is not followed by comma (,) or end of list (]).')
                return json_obj
            except JSONDecodeError:
                next_char = self.stream.read(1)
                read_buffer += next_char
                while next_char != '}':
                    next_char = self.stream.read(1)
                    if next_char == '':
                        raise StopIteration
                    read_buffer += next_char

হাই, এটি দুর্দান্ত দরকারী তবে আপনি কী দেখিয়ে দিতে পারেন যে আমি জেএসন ফাইলটি লোড করতে ক্লাসটি কীভাবে ব্যবহার করতে পারি?
গান0089

3

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

আমার ক্ষেত্রে, আমি কোনও ফাইল থেকে একই জিনিস টাইপের "সুন্দর-মুদ্রিত" JSON অবজেক্টগুলি পড়ার চেষ্টা করছিলাম। এটি আমাকে পদ্ধতির অনুকূলকরণের অনুমতি দেয়; আমি ফাইলটি লাইন বাই লাইন পড়তে পারতাম, কেবল তখনই ডিকোডিং করতাম যখন ঠিক "}" ধারণ করে একটি লাইন পাই:

def iterload(stream):
    buf = ""
    dec = json.JSONDecoder()
    for line in stream:
        line = line.rstrip()
        buf = buf + line
        if line == "}":
            yield dec.raw_decode(buf)
            buf = ""

যদি আপনি এক-প্রতি-লাইন কমপ্যাক্ট জেএসওএন নিয়ে কাজ করছেন যা স্ট্রিং লিটারালগুলিতে নিউলাইনগুলি থেকে দূরে রয়েছে, তবে আপনি নিরাপদে এই পদ্ধতির আরও সহজ করতে পারবেন:

def iterload(stream):
    dec = json.JSONDecoder()
    for line in stream:
        yield dec.raw_decode(line)

স্পষ্টতই, এই সাধারণ পন্থাগুলি কেবল খুব নির্দিষ্ট ধরণের জেএসএনের জন্য কাজ করে। যাইহোক, যদি এই অনুমানগুলি ধরে রাখে তবে এই সমাধানগুলি সঠিক এবং দ্রুত কাজ করে।


2

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

import json

def yield_multiple_value(f):
    '''
    parses multiple JSON values from a file.
    '''
    vals_str = f.read()
    decoder = json.JSONDecoder()
    try:
        nread = 0
        while nread < len(vals_str):
            val, n = decoder.raw_decode(vals_str[nread:])
            nread += n
            # Skip over whitespace because of bug, below.
            while nread < len(vals_str) and vals_str[nread].isspace():
                nread += 1
            yield val
    except json.JSONDecodeError as e:
        pass
    return

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

def yield_multiple_value(f):
    '''
    parses multiple JSON values from a file.
    '''
    vals_str = f.read()
    decoder = json.JSONDecoder()
    while vals_str:
        val, n = decoder.raw_decode(vals_str)
        #remove the read characters from the start.
        vals_str = vals_str[n:]
        # remove leading white space because a second call to decoder.raw_decode()
        # fails when the string starts with whitespace, and
        # I don't understand why...
        vals_str = vals_str.lstrip()
        yield val
    return

Json.JSONDecoder ক্লাস সম্পর্কে নথিপত্রে পদ্ধতিটি কাঁচা_ডেকোড https://docs.python.org/3/library/json.html#encoders- এবং- ডেকোডারগুলিতে নিম্নলিখিত রয়েছে:

এটি স্ট্রিং থেকে জেএসওএন ডকুমেন্টটি ডিকোড করতে ব্যবহার করা যেতে পারে যার শেষে রয়েছে বহিরাগত ডেটা।

এবং এই বহিরাগত ডেটা সহজেই অন্য জেএসওনের মান হতে পারে। অন্য কথায় পদ্ধতিটি এই উদ্দেশ্যটি মাথায় রেখে লেখা যেতে পারে।

উপরের ফাংশনটি ব্যবহার করে ইনপুট.টিএসটিএস্ট সহ আমি আসল প্রশ্নটিতে উপস্থাপিত উদাহরণ আউটপুটটি পাই।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.