Python'da Sözlüğe Dize


126

Bu yüzden bunun için çok zaman harcadım ve bana öyle geliyor ki basit bir düzeltme olmalı. Kullanıcıları siteme kaydetmek için Facebook'un Kimlik Doğrulamasını kullanmaya çalışıyorum ve bunu sunucu tarafında yapmaya çalışıyorum. Erişim belirtecimi aldığım noktaya geldim ve şu adrese gittim:

https://graph.facebook.com/me?access_token=MY_ACCESS_TOKEN

Aradığım bilgiyi şuna benzer bir dizge olarak alıyorum:

{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}

Görünüşe göre bunu kullanabilmem gerekiyor dict(string)ama şu hatayı alıyorum:

ValueError: dictionary update sequence element #0 has length 1; 2 is required

Bu yüzden Pickle'ı kullanmayı denedim, ancak şu hatayı aldım:

KeyError: '{'

Onu django.serializersserileştirmeyi denedim ama benzer sonuçlar aldım . Düşüncesi olan var mı? Cevabın basit olması gerektiğini hissediyorum ve sadece aptalca davranıyorum. Herhangi bir yardım için teşekkürler!


Dizeyi Python olarak değerlendirmek istiyorsanız, dizenizi değiştirmeniz gerekebilir: tanımlanmadıkça "verified":truebaşarısız olur true. Yoksa kullanabilirsiniz "verified":Trueveya "verified":"true".
Matt Curtis

2
@Matt: graph.facebook.com'un çıktı formatını değiştirebileceğinden şüpheliyim.
Fred Nurk

@Fred: Sorunun başlığına ("Python'da Dizeden Sözlüğe") bakılırsa, sanırım onu ​​aramadan önce Python'dan değiştirebilir ast.literal_eval(). Yine de (gözden geçirilmiş) cevabınız doğrudur - JSON serisini kaldırıcı daha iyi bir çözümdür.
Matt Curtis

1
@MattCurtis: Bunu sağlam bir şekilde değiştirmek (ast.literal_eval'den önce) ilk etapta JSON olarak ayrıştırmayı gerektirir. OP'nin dict (some_string) ile yapmaya çalıştığı şeyi yapmanın doğru yolu olarak ast.literal_eval'den bahsetmiştim.
Fred Nurk

@Fred: Sanırım aynı fikirde olduğumuzu düşünüyoruz :-)
Matt Curtis

Yanıtlar:


239

Bu veriler JSON'dur ! Python 2.6+ üzerindeyseniz yerleşik jsonmodülü kullanarak serisini kaldırabilirsiniz , aksi takdirde mükemmel üçüncü taraf simplejsonmodülünü kullanabilirsiniz .

import json    # or `import simplejson as json` if on Python < 2.6

json_string = u'{ "id":"123456789", ... }'
obj = json.loads(json_string)    # obj now contains a dict of the data

5
uÖrnek JSON dizenizin önüne neden koydunuz ?
John Machin

2
@John: Bir Unicode dizesini gösterir . Çoğunlukla alışkanlığım dışında ortaya koyuyorum, ancak muhtemelen Facebook API, içinde ASCII olmayan karakterler bulunan verileri geri verebilir; bu durumda, veriler kodlanacak (muhtemelen UTF-8'de) ve decode()-ing bir unicodedizge oluşturacaktı - bu benim örneğimde kullandığım şeydi. Ayrıca, bu sayfada JSON'un her zaman Unicode'da olduğundan bahseder (terimi arayın, yaklaşık yarı yolda)
Cameron

3
Python'da küçük bir unicode değişmezi olduğunu gösterir. Alışkanlık iyi bir sebep değil. "JSON metninin karakter kodlaması her zaman Unicode'dur." - [Uu] nikot bir kodlama DEĞİLDİR. Json.loads () 'un beklediği şey, tipik olarak ASCII'de kodlanmış bir str nesnesi olan "kablo üzerinden" sahip olduğunuz şeydir. Json.loads () bir unicode nesnesini kasıtlı olarak besleyeceğiniz tek durum, garip bir kişinin onu UTF-16'da ilettiği ve belgelendiği gibi sizin de kodunu çözmeniz gerektiğidir.
John Machin

1
@John: Evet, küçük-u unicodebir Unicode (büyük-U uygun isim) dizesi içeren Python türüdür. Ayrıca Unicode'un bir kodlama olmadığına da katılıyorum, bu yüzden belki de o sayfayı referans olarak göstermemeliyim. Yine de unicodedizeleri iletmekten kaçınmak için bir neden yok json.loads- dokümanlar bunun tamamen kabul edilebilir olduğunu açıkça belirtiyor ve daha açık olduğu için önceden kodu çözülmüş bir dizeyi kullanmayı seviyorum.
Cameron

8
@John: Bilgiçlik tasladığım için üzgünüm, ancak ASCII'de kodlanmış json.loads()bir strnesne beklemiyor - ya UTF-8 ilestr kodlanmış bir nesne ya da bir nesne (ya da bir nesne artı açık bir kodlama) bekliyorunicodestr
Cameron

19

Python değişmezlerini değerlendirmek için ast.literal_eval kullanın . Bununla birlikte, sahip olduğunuz şey JSON'dur (örneğin, "true" yu not edin), bu nedenle bir JSON seriyi kaldırıcı kullanın.

>>> import json
>>> s = """{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}"""
>>> json.loads(s)
{u'first_name': u'John', u'last_name': u'Doe', u'verified': True, u'name': u'John Doe', u'locale': u'en_US', u'gender': u'male', u'email': u'jdoe@gmail.com', u'link': u'http://www.facebook.com/jdoe', u'timezone': -7, u'updated_time': u'2011-01-12T02:43:35+0000', u'id': u'123456789'}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.