2012-12-21 11 views
2

루프를 통과하고 값의 유효성을 검사 할 파이썬 사전 경로를 동적으로 생성하는 데 문제가 있습니다. 다음과 같이하고 싶습니다.동적 파이썬 사전 참조 경로 만들기 경로

Requests 1.0을 사용하여 API 호출을하고 사전에 JSON 응답을 저장하십시오.

{ 
"status": "OK", 
"items": [ 
    { 
     "name": "Name 1", 
     "id": 0, 
     "address":{ 
      "city": "New York", 
     } 
    }, 
    { 
     "name": "Name 2", 
     "id": 1, 
     "address":{ 
      "city": "New York", 
     } 
    }, 
    { 
     "name": "Name 3", 
     "id": 2, 
     "address":{ 
      "city": "New York", 
     } 
    }] 
} 

가 검증하는 기능에 응답 DICT, 필드 보내기 다음과 같이

response = requests.get(path/to/file.json).json() 

응답 객체

가 포맷됩니다. 이 함수는 응답 객체를 사용하여 필드 항목을 추가하여 경로를 정의한 다음 값에 대해 유효성을 검사합니다. 그래서 이론적으로는 다음과 같습니다

response[field] = value 

내가이 일을 쓴 코드 것은이었다

def dynamic_assertion(response, field, value): 
     i = 0 
     stations = "response['items']" 
     count = len(response['items']) 
     while i < count: 
      path = '%s[%s]%s' % (stations, i, field) 
      path = path.strip("") 
      if path != value: 
       print type(path) 
       return False 
      i += 1 
     return True 

dynamic_assertion(response, "['address']['city']", "New York") 

는 내가 경로 문자열을 생성하면 더 이상 객체임을 깨닫게합니다. 응답 객체를 유지하고 통과 할 참조 경로를 추가 할 수있는 방법으로 어떻게 만들 수 있습니까? 이게 가능하니?!

답변

1

중첩 된 사전의 개별 키를 나타내는 튜플 또는 문자열 목록을 사용하여 단일 path 문자열을 피하는 것이 나을 것 같습니다. 즉 "['address']['city']"field 인수가 아닌 ("address", "city")으로 전달됩니다. 그럼 그냥 최종 값이 올바른 경우 키를 통해 이동하여 볼 수있는 루프가 필요합니다 (질문에서 response DICT를 제공)

def dynamic_assertion(response, field, value): 
    for item in response["items"]: 
     for key in field: 
      item = item[key] # go deeper into the nested dictionary 
     if item != value: 
      return False # raising an exception might be more Pythonic 
    return True 

예 출력 :

>>> dynamic_assertion(response, ("address", "city"), "New York") 
True 
>>> dynamic_assertion(response, ("address", "city"), "Boston") 
False 
>>> response["items"][2]["address"]["city"] = "Boston" # make response invalid 
>>> dynamic_assertion(response, ("address", "city"), "New York") 
False 
>>> dynamic_assertion(response, ("address", "city"), "Boston") 
False 
+0

감사합니다! 그건 완전히 의미가 있습니다. 한 번에 모든 경로를 만들려고 애를 썼기 때문에이 반복 기술을 고려조차하지 않았습니다. 간단한 천재! 다시 한 번 감사드립니다! – duepayer