আমি কীভাবে কোনও ফাইলে JSON ডেটা লিখব?


1121

আমার কাছে ভেরিয়েবলে জেএসএন ডেটা জমা আছে data

আমি এটি টেস্টিংয়ের জন্য একটি পাঠ্য ফাইলে লিখতে চাই যাতে প্রতিবার সার্ভার থেকে ডেটা ধরতে হয় না।

বর্তমানে, আমি এটি চেষ্টা করছি:

obj = open('data.txt', 'wb')
obj.write(data)
obj.close

এবং আমি এই ত্রুটিটি পাচ্ছি:

প্রকারের ত্রুটি: অবশ্যই স্ট্রিং বা বাফার হতে হবে, ডিক নয়

কিভাবে এটি ঠিক করবেন?

উত্তর:


2038

আপনি প্রকৃত JSON অংশটি ভুলে গেছেন - dataএকটি অভিধান এবং এখনও JSON- এনকোডেড নয়। এটা লিখুন ভালো সর্বাধিক সামঞ্জস্য (পাইথন 2 এবং 3) জন্য:

import json
with open('data.json', 'w') as f:
    json.dump(data, f)

একটি আধুনিক সিস্টেমে (অর্থাত পাইথন 3 এবং ইউটিএফ -8 সমর্থন), আপনি এর সাথে একটি ভাল ফাইল লিখতে পারেন

import json
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=4)

8
: এই serializing জন্য সহায়ক হতে পারে stackoverflow.com/questions/4512982/...
jedierikb

12
আপনি json.dump বা json.dump বোঝাতে চান?
টার্মিনালডিলেটতে

153
@ টার্মিনাল ডিলিট json.dumpএকটি ফাইল বা ফাইলের মতো বস্তুতে লেখেন, যেখানে json.dumpsএকটি স্ট্রিং প্রদান করে।
ফিহাগ

24
বিটিডব্লিউ: ডেটা ব্যবহার পুনরায় পড়তে: খোলা ('ডেটা.টিএসটিএসটি') হিসাবে ইনফাইলে: ডি = জেসন.লোড (ইনফাইলে)। দেখুন: এই উত্তর
ক্লাস

9
@ এনেভর না, এই উত্তরটি সূক্ষ্ম সুরে দেওয়া হয়েছে। পাইথন 3-এ, json.dumpএকটি বাইনারি ফাইল নয়, একটি পাঠ্য ফাইলে লেখেন। TypeErrorফাইলটি যদি খোলা থাকে তবে আপনি একটি পেয়ে যাবেন wb। পুরানো পাইথন সংস্করণে, উভয়ই wন্যানড wbকাজ করে। একটি প্রকৃত এনকোডিং প্রয়োজন হয় না কারণ কেবলমাত্র আউটপুট json.dumpকেবলমাত্র ASCII হয় ডিফল্টরূপে। আপনি যদি নিশ্চিত হয়ে যেতে পারেন যে আপনার কোডটি কখনও লিগ্যাসি পাইথন সংস্করণে চালিত হয় না এবং আপনি এবং JSON ফাইলের হ্যান্ডলারটি সঠিকভাবে নন-এএসসিআইআই হ্যান্ডেল করতে পারে তবে আপনি একটি নির্দিষ্ট করে সেট করতে পারেন ensure_ascii=False
ফিহাগ

267

পাইথন 2 ব্যবহারের গ্রহণযোগ্য উত্তরে ascii -encoded এর বিপরীতে utf8 -encoded ফাইলটি পেতে :

import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
  f.write(json.dumps(data, ensure_ascii=False))

কোডটি পাইথন 3 এ আরও সহজ:

import json
with open('data.txt', 'w') as f:
  json.dump(data, f, ensure_ascii=False)

উইন্ডোজে, এখনও encoding='utf-8'যুক্তিটি openপ্রয়োজনীয়।

মেমরি (এর ফলাফলে ডেটার একটি এনকোডেড কপি সংরক্ষণ এড়াতে dumps) এবং আউটপুট UTF8 এনকোডেড উভয় পাইথন 2 এবং 3, ব্যবহারে bytestrings:

import json, codecs
with open('data.txt', 'wb') as f:
    json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)

codecs.getwriterপাইথন 3 এ কলটি রিডানড্যান্ট তবে পাইথন 2 এর জন্য প্রয়োজনীয়


পাঠযোগ্যতা এবং আকার:

এর ব্যবহার ensure_ascii=Falseআরও ভাল পঠনযোগ্যতা এবং ছোট আকার দেয়:

>>> json.dumps({'price': '€10'})
'{"price": "\\u20ac10"}'
>>> json.dumps({'price': '€10'}, ensure_ascii=False)
'{"price": "€10"}'

>>> len(json.dumps({'абвгд': 1}))
37
>>> len(json.dumps({'абвгд': 1}, ensure_ascii=False).encode('utf8'))
17

আরও পতাকা যোগ করে পাঠযোগ্যতা উন্নতি indent=4, sort_keys=True(যেমন দ্বারা প্রস্তাবিত dinos66 অফ আর্গুমেন্ট করার জন্য) dumpবা dumps। এইভাবে আপনি কিছুটা বড় ফাইল আকারের দামে জসন ফাইলে একটি সুন্দর ইন্টেন্টেড সাজানো কাঠামো পাবেন।


5
unicodeপ্রযোজন নেই - ফল json.dumpsইতিমধ্যে একটি ইউনিকোড অবজেক্ট। নোট করুন যে এটি 3.x এ ব্যর্থ হয়েছে, যেখানে আউটপুট ফাইল মোডের এই পুরো গণ্ডগোলটি পরিষ্কার হয়ে গেছে, এবং জেসন সর্বদা অক্ষরের স্ট্রিংগুলি (এবং অক্ষর I / O) এবং কখনই বাইট ব্যবহার করে না।
ফিহাগ

4
2.x এ type(json.dumps('a'))হয় <type 'str'>। এমনকি type(json.dumps('a', encoding='utf8'))হয় <type 'str'>
অ্যান্টনি হ্যাচকিন্স

4
হ্যাঁ, ৩.x জেসন স্ট্রিংগুলি ব্যবহার করে, তবুও ডিফল্ট এনকোডিংটি আসকি। আপনাকে স্পষ্ট করে বলতে হবে যে আপনি utf83.x তেও চান। উত্তর আপডেট করেছেন।
অ্যান্টনি হ্যাচকিন্স

4
ওহ, আপনি পুরোপুরি ঠিক বলেছেন - আমার অবশ্যই কিছু বিভ্রান্ত হওয়া উচিত। বিস্তারিত জন্য +1।
ফিহাগ

1
পাইথন 3.x উত্তর আমার জন্য কাজ করেছে যদিও আমি 2.7 ব্যবহার করছি। 2.x উত্তর একটি ত্রুটি ফিরিয়ে: 'ascii' codec can't decode byte 0xf1 in position 506755: ordinal not in range(128)। সন্দেহ হলে, 3.x উত্তর ব্যবহার করুন!
ব্লেয়ার

162

আমি পূর্বোক্ত জবাবগুলির সাথে সামান্য সংশোধন করে উত্তর দেব এবং তা হ'ল একটি পূর্বনির্ধারিত জেএসওএন ফাইল লিখুন যা মানুষের চোখ আরও ভাল পড়তে পারে। এই জন্য, 4 স্থান অক্ষর sort_keysহিসাবে Trueএবং পাস করুন indentএবং আপনি যেতে ভাল। আপনার জেএসওএন ফাইলে আসকি কোডগুলি রচিত হবে না তা নিশ্চিত করারও যত্ন নিন:

with open('data.txt', 'w') as outfile:
     json.dump(jsonData, outfile, sort_keys = True, indent = 4,
               ensure_ascii = False)

2
এখনও UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc'
পাচ্ছি

1
@ সিরবেনবেজি আপনি যে স্ট্রিং অনুসরণ করতে লিখতে চেষ্টা করছেন তা নিশ্চিত করুন: str.decode ('utf-8')।
আম্বোদি

1
@ সিরবেনবেঞ্জি আপনি কোডেকগুলি ব্যবহার করেও চেষ্টা করতে পারেন, ডাইনোস below66 এর নীচে যেমন উল্লেখ করা হয়েছে
শিব

আপনাকে # -*- coding: utf-8 -*-
শেবাংয়ের

2
সাজানো_কি এবং ইনডেন্টের জন্য +1। @ আয়েসদে এই লাইনটি যুক্ত করা ভাল নয় কারণ এটি এই ধারণাটি তৈরি করবে যে এই সমাধানটি পাইথন 2 এর সাথে কাজ করে যা এটি নয় ( UnicodeEncodeErrorঅ-এসকিআই ডেটা সহ)। বিশদ জন্য আমার সমাধান দেখুন ।
অ্যান্টনি হ্যাচকিন্স

111

পাইথন 2 + 3 দিয়ে JSON ফাইলগুলি পড়ুন এবং লিখুন; ইউনিকোড নিয়ে কাজ করে

# -*- coding: utf-8 -*-
import json

# Make it work for Python 2+3 and with Unicode
import io
try:
    to_unicode = unicode
except NameError:
    to_unicode = str

# Define data
data = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],
        'a string': 'bla',
        'another dict': {'foo': 'bar',
                         'key': 'value',
                         'the answer': 42}}

# Write JSON file
with io.open('data.json', 'w', encoding='utf8') as outfile:
    str_ = json.dumps(data,
                      indent=4, sort_keys=True,
                      separators=(',', ': '), ensure_ascii=False)
    outfile.write(to_unicode(str_))

# Read JSON file
with open('data.json') as data_file:
    data_loaded = json.load(data_file)

print(data == data_loaded)

এর পরামিতিগুলির ব্যাখ্যা json.dump:

  • indent: প্রতিটি প্রবেশের প্রবেশের জন্য 4 টি স্পেস ব্যবহার করুন, যেমন একটি নতুন ডিক শুরু হলে (অন্যথায় সমস্ত এক লাইনে থাকবে),
  • sort_keys: অভিধানের কীগুলি বাছাই করুন। আপনি যদি একটি ডিফ সরঞ্জামের সাথে জসন ফাইলগুলি তুলনা করতে / সংস্করণ নিয়ন্ত্রণে রাখতে চান তবে এটি কার্যকর useful
  • separators: পাইথনকে পেছনের শ্বেত স্পেস যোগ করা থেকে বিরত রাখতে

একটি প্যাকেজ সহ

mpuএকটি অতি সাধারণ এবং সহজে মনে রাখা সহজ জন্য আমার ইউটিলিটি প্যাকেজটি দেখুন :

import mpu.io
data = mpu.io.read('example.json')
mpu.io.write('example.json', data)

JSON ফাইল তৈরি করেছে

{
    "a list":[
        1,
        42,
        3.141,
        1337,
        "help",
        "€"
    ],
    "a string":"bla",
    "another dict":{
        "foo":"bar",
        "key":"value",
        "the answer":42
    }
}

সাধারণ ফাইল সমাপ্তি

.json

বিকল্প

আপনার প্রয়োগের জন্য, নিম্নলিখিতগুলি গুরুত্বপূর্ণ হতে পারে:

  • অন্যান্য প্রোগ্রামিং ভাষা দ্বারা সমর্থন
  • পড়া / লেখার পারফরম্যান্স
  • সংক্ষিপ্ততা (ফাইলের আকার)

আরও দেখুন: ডেটা সিরিয়ালাইজেশন ফর্ম্যাটগুলির তুলনা

আপনি যদি কনফিগারেশন ফাইলগুলি তৈরির পরিবর্তে কোনও উপায় সন্ধান করছেন, আপনি পাইথনে আমার সংক্ষিপ্ত নিবন্ধ কনফিগারেশন ফাইলগুলি পড়তে চাইতে পারেন


2
নোট করুন যে force_asciiপতাকাটি Trueডিফল্টরূপে। আপনার জাসন ফাইলে "\u20ac"প্রত্যেকটির জন্য অপঠনযোগ্য 6-বাইট সিকোয়েন্স থাকবে (পাশাপাশি অন্য কোনও অ-এসকিআই চরিত্র)।
অ্যান্টনি হ্যাচকিন্স

আপনি লেখার জন্য openপড়ার জন্য ব্যবহার করেন না কেন io.open? পড়ার জন্যও কি এটি ব্যবহার করা সম্ভবio.open ? যদি তা হয় তবে কোন পরামিতিগুলি পাস করা উচিত?
মিকাহ জোল্টু

23

আপনারা যারা গ্রীক বা অন্যান্য "বহিরাগত" ভাষাগুলি যেমন আমার মতো ডাম্প করার চেষ্টা করছেন তবে তাদের কাছেও সমস্যা (ইউনিকোড ত্রুটি) যেমন অদ্ভুত অক্ষর যেমন শান্তি প্রতীক (\ u262E) বা অন্যান্য যেগুলি প্রায়শই জেসন ফর্ম্যাটেড ডেটাতে থাকে টুইটারের মতো সমাধানটি নীচের মত হতে পারে (সাজ্ট_কিগুলি স্পষ্টতই alচ্ছিক):

import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
     f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))

1
+1 টি দস্তাবেজ python3 builtin বিশেষ পরামর্শ দেওয়া হচ্ছে যদিও openএবং assotiated io.openউপর codecs.openএই ক্ষেত্রে এটি একটি চমৎকার পিছন সামঞ্জস্যপূর্ণ হ্যাক হয়। পাইথন 2 এ io.open এর codecs.openচেয়ে বেশি "সর্বস্বাদী" (এটি স্ট্র এবং ইউনিকোড উভয়ই "খেতে" পারে, প্রয়োজনে রূপান্তরকারী)। যে কেউ বলতে পারেন যে codecs.openইনপুটটিতে ইউনিকোড স্ট্রিংয়ের উপস্থিতির উপর নির্ভর করে json.dumpsবিভিন্ন ধরণের অবজেক্ট ( str/ unicode) উত্পন্ন করার জন্য এই তিরস্কারটি ক্ষতিপূরণ দেয়।
অ্যান্টনি হ্যাচকিন্স

10

মন্তব্যগুলিতে যুক্ত করার মতো পর্যাপ্ত খ্যাতি আমার নেই, তাই আমি এই বিরক্তিকর টাইপ এররের কিছু অনুসন্ধানগুলি এখানেই লিখছি:

মূলত, আমি মনে করি এটি কেবল json.dump()পাইথন 2 এ ফাংশনটিতে একটি ত্রুটি - এটি কোনও পাইথন (অভিধান / তালিকা) অ-ASCII অক্ষরযুক্ত ডেটা ডাম্প করতে পারে না, এমনকি আপনি encoding = 'utf-8'প্যারামিটার দিয়ে ফাইলটি খোলেন । (যেমন আপনি কিছু করেন না)। তবে, json.dumps()পাইথন 2 এবং 3 উভয় ক্ষেত্রেই কাজ করে।

এটি চিত্রিত করার জন্য, ফিহাগের উত্তর অনুসরণ করে: তার উত্তরের কোডটি পাইথন 2-এ ব্যতিক্রম সহ ভেঙে যায় TypeError: must be unicode, not str, যদি dataঅ-এএসসিআইআই অক্ষর থাকে। (পাইথন ২.7..6, ডেবিয়ান):

import json
data = {u'\u0430\u0431\u0432\u0433\u0434': 1} #{u'абвгд': 1}
with open('data.txt', 'w') as outfile:
    json.dump(data, outfile)

এটি পাইথন 3 এ দুর্দান্ত কাজ করে।


আপনি যখন কিছু ভুল বলে দাবি করেন তখন কারণ দিন। @ ডাকনাম ব্যবহার করুন যাতে ব্যক্তিটি অবহিত হয়। আপনি মন্তব্য লিখতে পারবেন না, তবে আপনি মন্তব্যগুলি পড়তে পারেন। প্রথম মন্তব্যে আমার জবাব হিসাবে ইতিমধ্যে বলা হয়েছে, চেষ্টা করুন data = {'asdf': 1}। আপনি TypeErrorআপনার (দ্বিতীয়) রূপটি দিয়ে কুখ্যাত পাবেন ।
অ্যান্টনি হ্যাচকিন্স

সম্পর্কিত ensure_ascii- আপনি যদি একটি "আসল" utf8 আউটপুট পেতে চান তবে এটি প্রয়োজনীয়। এটি ছাড়া আপনার এই পতাকার সাথে অক্ষর প্রতি 2 বাইটের বিপরীতে রাশিয়ান চিঠিতে 6 বাইটের সমতল আসকি থাকবে।
অ্যান্টনি হ্যাচকিন্স

@AntonyHatchkins আপনার জন্য সঠিক unicode()অংশ। আমি কেবল ioপাইথন 2 এ প্যাকেজটির জন্য উপলব্ধি করেছি , write()দরকার unicodeনেই str
ইবিক

1
এই কোডটি আমার জন্য পাইথন ২. De. De, ডেবিয়ান (ডিসেম্বর 10 2010) দিয়েও কাজ করে। পাশাপাশি পাইথন 2.7.7 বা পাইথন 3 সহ with আবার একবার দেখুন, plz।
অ্যান্টনি হ্যাচকিনস

7

JSON ব্যবহার করে json.dump () বা json.dumps () ব্যবহার করে ফাইলটিতে একটি ডেটা লিখুন । ফাইলে ডেটা সংরক্ষণ করার জন্য এটি লিখুন।

import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
    json.dump(data, txtfile)

তালিকার এই উদাহরণটি একটি ফাইলের জন্য সঞ্চয়।


এটি অনুরূপ তবে উদাহরণ সহকারে
বিশাল গেদিয়া

5

ইন্ডেন্টেশন সহ JSON লিখতে, "সুন্দর মুদ্রণ":

import json

outfile = open('data.json')
json.dump(data, outfile, indent=4)

এছাড়াও, আপনার যদি ভুলভাবে ফর্ম্যাটেড জেএসওএন ডিবাগ করতে হয় এবং একটি সহায়ক ত্রুটি বার্তা চান তবে import simplejsonলাইব্রেরিটি ব্যবহার করুন import json(ফাংশনগুলি একই হওয়া উচিত)


4
json.dump(data, open('data.txt', 'wb'))

2
এটি @ ফিহাগের উত্তরের মতো একই কাজ করে তবে এটি সর্বদা কাজ করার গ্যারান্টিযুক্ত নয়। যেমন কোড বিবেচনা করুন: f = open('1.txt', 'w'); f.write('a'); input()। এটি চালান এবং তারপরে এটি SYGTERM ( Ctrl-Zতারপরে kill %1লিনাক্স, Ctrl-Breakউইন্ডোজে)। 1.txt0 বাইট হবে। কারণ লিখিত বাফার করা হয়েছিল এবং SYGTERM হওয়ার মুহুর্তে ফাইলটি বন্ধ করা হয়নি। withব্লক গ্যারান্টি দেয় যে ফাইলটি সর্বদা 'চেষ্টা / শেষ' ব্লকের মতো বন্ধ হয়ে যায় তবে ছোট হয়।
অ্যান্টনি হ্যাচকিন্স

3

একটি ফাইলে JSON লেখা Writ

import json

data = {}
data['people'] = []
data['people'].append({
    'name': 'Scott',
    'website': 'stackabuse.com',
    'from': 'Nebraska'
})
data['people'].append({
    'name': 'Larry',
    'website': 'google.com',
    'from': 'Michigan'
})
data['people'].append({
    'name': 'Tim',
    'website': 'apple.com',
    'from': 'Alabama'
})

with open('data.txt', 'w') as outfile:
    json.dump(data, outfile)

একটি ফাইল থেকে জেএসএন পড়া হচ্ছে

import json

with open('data.txt') as json_file:
    data = json.load(json_file)
    for p in data['people']:
        print('Name: ' + p['name'])
        print('Website: ' + p['website'])
        print('From: ' + p['from'])
        print('')

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

গাইডের জন্য ঠিক আছে ধন্যবাদ
iman

2

যদি আপনি কোনও জসন ফর্ম্যাট ব্যবহার করে কোনও ফাইলের মধ্যে একটি পান্ডাস ডাটাফ্রেম লেখার চেষ্টা করছেন তবে আমি এটির পরামর্শ দিই

destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()

2

পূর্ববর্তী সমস্ত উত্তর এখানে সঠিক একটি খুব সাধারণ উদাহরণ:

#! /usr/bin/env python
import json

def write_json():
    # create a dictionary  
    student_data = {"students":[]}
    #create a list
    data_holder = student_data["students"]
    # just a counter
    counter = 0
    #loop through if you have multiple items..         
    while counter < 3:
        data_holder.append({'id':counter})
        data_holder.append({'room':counter})
        counter += 1    
    #write the file        
    file_path='/tmp/student_data.json'
    with open(file_path, 'w') as outfile:
        print("writing file to: ",file_path)
        # HERE IS WHERE THE MAGIC HAPPENS 
        json.dump(student_data, outfile)
    outfile.close()     
    print("done")

write_json()

এখানে চিত্র বর্ণনা লিখুন


1

গৃহীত উত্তর ঠিক আছে। যাইহোক, আমি এটি ব্যবহার করে "" জসন সিরিয়ালাইজযোগ্য নয় "ত্রুটিযুক্ত হয়েছি।

open("file-name.json", 'w')আউটপুট হিসাবে আমি এটি কীভাবে স্থির করেছি তা এখানে :

output.write(str(response))

যদিও এটি তৈরি করা জসন ফাইলটিতে ডাবল উদ্ধৃতি থাকবে না এটি ঠিক মতো নয়, তবে আপনি যদি দ্রুত এবং নোংরা খুঁজছেন তবে এটি দুর্দান্ত।


0

নীচে JSON ডেটা কোনও ফাইলে লেখা যেতে পারে

hist1 = [{'val_loss': [0.5139984398465246],
'val_acc': [0.8002029867684085],
'loss': [0.593220705309384],
'acc': [0.7687131817929321]},
{'val_loss': [0.46456472964199463],
'val_acc': [0.8173602046780344],
'loss': [0.4932038113037539],
'acc': [0.8063946213802453]}]

একটি ফাইল লিখুন:

with open('text1.json', 'w') as f:
     json.dump(hist1, f)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.