2016-02-04 57 views
6

Python 3.5.1'i kullanarak, her satırın JSON biçiminde olduğu bir metin dosyasına çektim: {"a": "windows", "b": "merdiven" Ben dosyasının ilk satırını baskı sorunum yok, bu yüzden dosya yolunun doğru olduğundan güven duyuyorumJSON nesnesi str değil, 'bayt' değil

the JSON object must be str, not 'bytes' 

: ...}

import json 
path = 'folder/data.txt' 
records=[json.loads(line) for line in open(path,'rb')] 

Ama hata aldı.

+3

Belki de 'b' kurtulmak senin 'aç' çağrı? https://docs.python.org/2/library/functions.html#open, dosyayı bir dize olarak alınmamasına bağlı olarak ikili biçimde yükleyeceğini söylüyor. – TW80000

+0

Dosyanın sadece bir satırını alırsanız, json'a yükleyebilir misiniz? Json.loads (file.readlines() [0]) ' –

+0

@ TW80000 gibi öneriniz sorunumu çözer. Ayrıca 'açık' aramada doğrudan kodlama = 'utf-8' geçmenin de işe yarayacağını öğrendim. Yorumun için teşekkür ederim. – Greg

cevap

3

Dosyayı metin modunda açın, ikili modda değil (muhtemelen JSON genellikle UTF-8 olarak depolandığından, sistem varsayılanını geçersiz kılmak için encoding='utf-8''u açıkça geçirerek). json modülünde yalnızca str girişi; İkili modunda açılmış bir dosyadan okuma bytes nesneleri döndürür:

# Using with statement just for good form; in this case it would work the 
# same on CPython, but on other interpreters or different CPython use cases, 
# it's easy to screw something up; use with statements all the time to build good habits 
with open(path, encoding='utf-8') as f: 
    records=[json.loads(line) for line in f] 
+0

Bu, uygun formu kullanmayla ilgili tavsiyeleriniz için teşekkür eder. Orijinal kodumda 'encoding =' utf-8 'için' rb 'anahtarını değiştirmek de işe yarıyor gibi görünüyor. – Greg

1

Dosyanın ikili gösterimi JSON modülü tarafından okunabilir olacak olmadığından, "rb" belirtmek istemiyorum. Muhtemelen "utf-8" kodlamasını ve "okumayı" istersiniz. DÜZENLEME: Aslında her ikisinin de varsayılanlar olduğunu söylemiştim, fakat çoğu işletim sisteminin farklı varsayılan kodlamaya sahip olduğu ve Python'un sistem ayarını open() 'de varsayılan olarak kullandığı dikkatimi çekti. Bu nedenle, kodlama ayarını açıkça "utf-8" olarak sağlamanızı öneririm.

json, "json.loads" yerine "json.loads" yerine "json.load" ile bir açık dosyadan yüklenmeyi destekler, böylece metin içinde okundu atlayabilir ve JSON'a gidebiliriz. Tek tek satırları "yüklemek" isteyeceğinizi sanmıyorum, çünkü bu muhtemelen geçerli JSON olmayacaktır.

import json 
# open has __enter__ and __exit__ functions, so we can call it as a guard 
# using "with" syntax and it'll close when the scope ends 
with open(r".\myjson.json", encoding="utf-8") as fh: 
    # load() is a convenience function to help us avoid iterating lines 
    # on our own. It calls loads() on the whole doc and returns an obj 
    json_obj = json.load(fh) 
print (json_obj) 
+1

UTF-8 her zaman varsayılan '' kodlama'' değildir, ['locale.getpreferredencoding (False)'] işlevini kullanarak platforma bağlı ayarlardan dinamik olarak belirlenir (https://docs.python.org/3/library/functions.html# açık). Girişin UTF-8 olduğunu biliyorsanız, açıkça belirtin. Benzer şekilde, eğer birisi JSON blobs tek satırlık bir satırda yazdıysa, tüm dosyayı bir kerede yükleyemezsiniz, çünkü birlikte alınan tüm dosya geçerli bir JSON değildir, satırlar yalnızca yasal JSON'dur. Ayrıca, json.load' sadece 'file.read()' olarak adlandırılır ve 'load''e geçer, yani ne' load' den daha iyi ne de daha kötüdür. Ayrıca, Py3 'print' parens ihtiyacı var. – ShadowRanger

+0

harika puanlar, @ShadowRanger. Load() vs loads() için, burada bir performans boşluğu olduğunu ima etmeyi istemedim, ancak kendi kodumuzda yazma/okuma/sürdürme gereği duymadığımız bir döngü var. Load() öğesinin kullanılması, genellikle işleri yapmak için pythonik bir yol olan daha az gürültüye sahiptir. Baskı, 2.7 tercümanında çalışıyordu (benim kötü ve sabit). UTF-8 tamamen haklı olduğunuzu düşünüyor ve bunu Windows'la (OP'nin durumunda hiç de gerekli değil) hazırlamalıydım. –

+0

Aslında, Windows'ta UTF-8'in varsayılan olduğunu sanmıyorum, genellikle Windows kod sayfalarından biri (örneğin, cp1252, genellikle kullanılmayan kontrol karakterlerinin bazılarının yerine yazdırılabilir karakterlerle değiştiren bir latin-1 varyasyonu), örneğin akıllı teklifler).Verilerin tümü ASCII ise, her iki şekilde de iyisiniz (hem UTF-8 hem de cp1252 ASCII üst kümesidir), yalnızca sorun yaşayacağınız ASCII aralığının dışına çıktığınızda. Kod sayfalarının yanı sıra, Windows genellikle her şey için UTF-16 kullanır; İnternetteki verilerle uğraşırken sadece UTF-8'i kabul eder (UTF-8 standarttır). – ShadowRanger

2

Dene: kayıtlar = [açık hat (yol, 'rb') için json.loads (. Satır kod çözme())]

İlgili konular