Mam dane JSON przechowywane w zmiennej data
.
Chcę to zapisać do pliku tekstowego w celu przetestowania, więc nie muszę za każdym razem pobierać danych z serwera.
Obecnie próbuję tego:
obj = open('data.txt', 'wb')
obj.write(data)
obj.close
I otrzymuję ten błąd:
TypeError: musi być łańcuchem lub buforem, a nie dyktować
Jak to naprawić?
json.dump
zapisuje do pliku lub obiektu podobnego do pliku, ajson.dumps
zwraca ciąg znaków.json.dump
zapisuje do pliku tekstowego, a nie pliku binarnego. Dostaniesz,TypeError
jeśli plik został otwarty za pomocąwb
. W starszych wersjach Python obaw
nandwb
działają. Wyraźne kodowanie nie jest konieczne, ponieważjson.dump
domyślnie wyjściem jest tylko ASCII. Jeśli masz pewność, że Twój kod nigdy nie jest uruchamiany w starszych wersjach języka Python, a Ty i moduł obsługi pliku JSON potrafisz poprawnie obsługiwać dane inne niż ASCII, możesz określić jeden i ustawićensure_ascii=False
.Aby uzyskać plik zakodowany w utf8 w przeciwieństwie do kodu zakodowanego w ascii w zaakceptowanej odpowiedzi dla Python 2, użyj:
Kod jest prostszy w Pythonie 3:
W systemie Windows
encoding='utf-8'
argument toopen
jest nadal konieczny.Aby uniknąć zapisania zakodowanej kopii danych w pamięci (wynik
dumps
) i wygenerować bajtowanie zakodowane w utf8 zarówno w Pythonie 2, jak i 3, użyj:codecs.getwriter
Rozmowa jest zbędna w Pythonie 3, ale konieczne dla Pythona 2Czytelność i rozmiar:
Zastosowanie
ensure_ascii=False
daje lepszą czytelność i mniejszy rozmiar:Dalsza poprawa czytelności poprzez dodanie flag
indent=4, sort_keys=True
(jak sugeruje dinos66 ) do argumentówdump
lubdumps
. W ten sposób uzyskasz ładnie wciętą posortowaną strukturę w pliku json, kosztem nieco większego rozmiaru pliku.źródło
unicode
Jest zbędny - wynikjson.dumps
jest już obiektem Unicode. Zauważ, że kończy się to niepowodzeniem w wersji 3.x, w której cały bałagan trybu plików wyjściowych został oczyszczony, a json zawsze używa ciągów znaków (i znaków we / wy) i nigdy nie bajtów.type(json.dumps('a'))
jest<type 'str'>
. Nawettype(json.dumps('a', encoding='utf8'))
jest<type 'str'>
.utf8
nawet w wersji 3.x. Zaktualizowałem odpowiedź.'ascii' codec can't decode byte 0xf1 in position 506755: ordinal not in range(128)
. W razie wątpliwości skorzystaj z odpowiedzi 3.x!Chciałbym odpowiedzieć z niewielką modyfikacją wyżej wymienionymi odpowiedziami, a mianowicie napisać wstępnie zapisany plik JSON, który ludzkie oczy mogą lepiej odczytać. W tym celu przekazać
sort_keys
jakTrue
iindent
z 4 znaków spacji i jesteś dobry, aby przejść. Zadbaj również o to, aby kody ascii nie były zapisywane w pliku JSON:źródło
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc'
# -*- coding: utf-8 -*-
poUnicodeEncodeError
z danymi innymi niż ascii). Zobacz szczegóły mojego rozwiązania .Odczytywanie i zapisywanie plików JSON za pomocą Python 2 + 3; współpracuje z Unicode
Objaśnienie parametrów
json.dump
:indent
: Użyj 4 spacji do wcięcia każdego wpisu, np. Po rozpoczęciu nowego nagrania (w przeciwnym razie wszystkie będą w jednym wierszu),sort_keys
: sortuj klucze słowników. Jest to przydatne, jeśli chcesz porównać pliki Json za pomocą narzędzia różnicowego / poddać je kontroli wersji.separators
: Aby uniemożliwić Pythonowi dodawanie końcowych białych znakówZ pakietem
Zajrzyj do mojego pakietu narzędzi,
mpu
aby uzyskać bardzo prosty i łatwy do zapamiętania:Utworzono plik JSON
Typowe zakończenia plików
.json
Alternatywy
W przypadku aplikacji ważne mogą być:
Zobacz także: Porównanie formatów serializacji danych
Jeśli szukasz sposobu na utworzenie plików konfiguracyjnych, możesz przeczytać mój krótki artykuł Pliki konfiguracyjne w Pythonie
źródło
force_ascii
flaga jestTrue
domyślnie. Będziesz miał nieczytelne"\u20ac"
sekwencje 6-bajtowe dla każdej€
w pliku json (jak również dla każdej innej postaci innej niż ascii).open
do czytania, aleio.open
do pisania? Czy można również używaćio.open
do czytania? Jeśli tak, jakie parametry należy przekazać?Dla tych z was, którzy próbują zrzucić greckie lub inne „egzotyczne” języki, takie jak ja, ale mają również problemy (błędy Unicode) z dziwnymi znakami, takimi jak symbol pokoju (\ u262E) lub innymi, które często są zawarte w danych sformatowanych przez JSON takich jak Twitter, rozwiązanie może wyglądać następująco (sort_keys jest oczywiście opcjonalny):
źródło
open
i towarzyszące jejio.open
sięcodecs.open
, w tym przypadku jest to również miły wstecznie kompatybilny Hack. W python2codecs.open
jest bardziej „wszystkożerny” niż io.open (może „jeść” zarówno str, jak i Unicode, konwertując w razie potrzeby). Można powiedzieć, że tocodecs.open
dziwactwo kompensujejson.dumps
dziwactwo generowania różnych typów obiektów (str
/unicode
) w zależności od obecności ciągów Unicode na wejściu.Nie mam wystarczającej reputacji, aby dodać w komentarzach, więc po prostu piszę tutaj niektóre z moich odkryć tego irytującego TypeError:
Zasadniczo myślę, że jest to błąd w
json.dump()
funkcji tylko w Pythonie 2 - Nie może zrzucić danych Pythona (słownika / listy) zawierających znaki spoza ASCII, nawet jeśli otworzysz plik zencoding = 'utf-8'
parametrem. (tzn. bez względu na to, co robisz). Alejson.dumps()
działa zarówno na Pythonie 2, jak i 3.Aby to zilustrować, podążając za odpowiedzią phihag: kod w jego odpowiedzi łamie się w Pythonie 2 z wyjątkiem
TypeError: must be unicode, not str
, jeślidata
zawiera znaki spoza ASCII. (Python 2.7.6, Debian):Działa to jednak dobrze w Pythonie 3.
źródło
data = {'asdf': 1}
. Otrzymasz rozgłosTypeError
ze swoim (drugim) wariantem.ensure_ascii
- jest to konieczne, jeśli chcesz uzyskać „prawdziwe” wyjście utf8. Bez niego będziesz miał zwykły ascii z 6 bajtami na rosyjską literę, w przeciwieństwie do 2 bajtów na znak z tą flagą.unicode()
. Właśnie uświadomiłem sobie, naio
opakowaniu w Pythonie 2,write()
potrzebujeunicode
, niestr
.Zapisz dane w pliku za pomocą JSON, użyj json.dump () lub json.dumps () . napisz w ten sposób, aby zapisać dane w pliku.
ten przykład na liście jest przechowywany w pliku.
źródło
Aby napisać JSON z wcięciem, „pretty print”:
Ponadto, jeśli chcesz debugować niepoprawnie sformatowany JSON i potrzebujesz pomocnego komunikatu o błędzie, użyj
import simplejson
biblioteki zamiastimport json
(funkcje powinny być takie same)źródło
źródło
f = open('1.txt', 'w'); f.write('a'); input()
. Uruchom go, a następnie SYGTERM go (Ctrl-Z
następnie w systemiekill %1
Linux,Ctrl-Break
w systemie Windows).1.txt
będzie miał 0 bajtów. Jest tak, ponieważ zapis został buforowany, a plik nie został opróżniony ani zamknięty w momencie wystąpienia SYGTERM.with
blok gwarantuje, że plik jest zawsze zamykany, podobnie jak blok „spróbuj / w końcu”, ale krótszy.Zapisywanie JSON do pliku
Odczytywanie JSON z pliku
źródło
jeśli próbujesz zapisać ramkę danych pandy w pliku w formacie json, poleciłbym to
źródło
Wszystkie poprzednie odpowiedzi są poprawne tutaj jest bardzo prosty przykład:
źródło
Przyjęta odpowiedź jest w porządku. Jednak natknąłem się na błąd „nie można serializować json”.
Oto jak to naprawiłem
open("file-name.json", 'w')
jako wyjście:output.write(str(response))
Chociaż nie jest to dobra poprawka, ponieważ plik json, który tworzy, nie będzie zawierał podwójnych cudzysłowów, ale jest świetny, jeśli szukasz szybkiego i brudnego.
źródło
Dane JSON można zapisać do pliku w następujący sposób
Napisz do pliku:
źródło