2016-03-24 11 views
2

Python'da, aynı verileri açıklayan JSON biçimlendirilmiş bir metin döndüren birçok web hizmetini arıyorum, ancak her biri farklı yapılandırılmış. Veriler arasında geçiş yapmak için bir düzine yol yazmak yerine, ortak bir temel yol ve ortak alan adı oluşturmaya çalışıyorum, ancak istenen alanı yakalayabilmek için dinamik bir isim oluşturmak için şimdi anlamıyorum. sokak adresini çağırırPython'da JSON'dan Değişkenleri Yakalamak için Dinamik Yol Oluşturma

servis1, "addr1" ise, "address1" diyorService2.

service1 Sokak adresine giden JSON yolu: ["results"] [0] ["locations"] [0] ["addr1"].

service2 Sokak adresine giden JSON yolu: ["query"] [0] ["address1"].

servis1 tepkisi: my ortak terimlerden

{ 
    "results":[ 
     { 
      "providedLocation":{ 
       "location":"123 Main St. Whoville" 
      }, 
      "locations":[ 
       { 
       "addr1":"123 Main St.", 
       "city":"Whoville" 
       } 
      ] 
     } 
    ] 
} 

ben adres yerleri arasında döngü ediyorum

[service1] 
base_path = '["results"][0]["locations"]' 
field  = "addr1" 
[service2] 
base_path = '["query"]' 
field  = 'address1' 

dosya translation.ini böyle döndürdü:

j   = json.loads(response.text) 
try: 
    for i in range(0,count_the_results()): 
     street_number = j[base_path][i][field] # multiple locations returned 

except KeyError: 
    print("street_number error again") 

Eval() kullanmayı denedim, ancak parantezleri düşürdü ([0]) hangi

j[eval(base_path)] 

Ben parçalar halinde base_path kırarak çalıştı ama eval hala bana

base_path = '["results"][0]' 
locations = '["locations"]' 
j[eval(str(base_path)+str(locations))] 

Ben tuşlarını kullanın, ama yine de her nasılsa

özgün bir yol inşa etmek olabilir alır yolunu bozar

j.get ("sonuç" {}) [0] .get ("yerleri") [i] [alan]

Yol oluştururken eksik olanı işaret edebilir misiniz, lütfen?

+0

Her listenin ilk sonucunu her zaman kullanmanın bir nedeni var mı? Örneklerinizdeki her iki servis modeli de çeşitli adreslere sahip olmayı destekler; Hepsini ele alabilecek şekilde kodlamamalısın? – Joe

+0

iyi soru, Joe. "Base_path", cevabın statik bir parçası olarak tanımladığım bölümdür - her zaman 1 öğe ve sadece "sonuç" (çoğul) olarak adlandırılır. Bunu, benim örneğimde, istenen alandan önce, [i] tarafından arttırılan, bilinmeyen bir liste sayısı takip eder. Cevabın için teşekkürler. – jim

+0

her zaman belirli bir dizgeyse tuşlara baktığınız bir adım adım yöntemini uygulayabilirsiniz. bu şekilde sadece değişkenin ismine sahip olmanız gerekir. –

cevap

1

Böyle yapabileceğini:

def get_item(response, path): 
    for item in path: 
     response = response[item] 
    return response 

# Assume we need the string 'qwerty' 
spam = {'spam': ['eggs', {'13': 'qwerty'}], 'eggs': 123} 
# Then that will be our path: 
path = ['spam', 1, '13'] 

print get_item(spam, path) 

O 'qwerty' yazdırır.


Bunu yapmanın kısa devre ve daha verimli (ama muhtemelen daha az anlaşılır) yolu böyle yerleşik reduce işlevini kullanmaktır:

def get_item(response, path): 
    return reduce(lambda x, y: x[y], path, response) 

diğer sorun yolunu saklamak için nasıl .ini dosyasında. Benim önerim JSON biçiminde yazmak, sonra örneğimde olduğu gibi yolu alacak json.loads() öğesine aktarmak olacaktır.

base_path = '["results", 0, "locations"]' 

Sen yapılandırmasındaki dize '["results", 0, "locations"]' olsun (bu bir sorun değil mi? Olabilir), json.loads

path = json.loads(path_string) 

iletecek ve get_item işlevinde kullanabilirsiniz.

+0

Önerilerinizi test edeceğim Ilya. Kendi dosyamdan json kullanarak değerlerimi yüklemeyi düşünmedim, bu yüzden bunu saatlerce hayal kırıklığına uğrattıktan sonra configparser için yeniden yazdım. – jim

+0

@jim Size hayal kırıklığı neden olduğu için özür dilerim, bunu önerdim çünkü kolayca bir JSON dizesini (ve herhangi bir diğer dize) kolayca yapılandırmanıza koyabileceğinizi düşündüm. Benim önerim programınızı 'configparser 'kullanmak için yeniden yazdıktan sonra mı çalıştı? –

+0

Yanlış anlamadan dolayı özür dilerim, beni hayal kırıklığına uğrattığınız anlamına gelmez - her şey kendi kendine uygulanmıştır :). Cevabınız harika ve her web servis sağlayıcısından test sonuçlarını kullanıyorum. Gerçekten günümü önerinle yaptın ve minnettarım. Bunu cevap olarak işaretleyeceğim. – jim