2010-04-03 21 views
30

que estoy tratando de urlencode un diccionario en Python con urllib.urlencode. El problema es que tengo que codificar una matriz.urlencode una matriz de valores

El resultado debe ser:

criterias%5B%5D=member&criterias%5B%5D=issue 
#unquoted: criterias[]=member&criterias[]=issue 

Pero el resultado que obtiene es:

criterias=%5B%27member%27%2C+%27issue%27%5D 
#unquoted: criterias=['member',+'issue'] 

He intentado varias cosas, pero me parece que no puede obtener el resultado correcto.

import urllib 
criterias = ['member', 'issue'] 
params = { 
    'criterias[]': criterias, 
} 
print urllib.urlencode(params) 

Si uso cgi.parse_qs para decodificar una cadena de consulta correcta, me sale esto como resultado:

{'criterias[]': ['member', 'issue']} 

Pero si puedo codificar ese resultado, aparece un resultado erróneo espalda. ¿Hay alguna manera de producir el resultado esperado?

+0

'cig.parse_qs' está en desuso (solo se conserva para compatibilidad con versiones anteriores), por lo que puede ser mejor utilizar' urlparse.parse_qs' – ChristopheD

+0

Gracias por la sugerencia. Solo lo usé para comparar, así que no se usa realmente. – Ikke

Respuesta

53

La solución es mucho más simple que las enumeradas anteriormente.

>>> import urllib 
>>> params = {'criterias[]': ['member', 'issue']} 
>>> 
>>> print urllib.urlencode(params, True) 
criterias%5B%5D=member&criterias%5B%5D=issue 

Nota Verdadero. Consulte http://docs.python.org/library/urllib.html#urllib.urlencode la variable de doseq.

Como nota al margen, no es necesario el [] para que funcione como una matriz (que es la razón por urllib no lo incluye). Esto significa que no necesita agregar el [] a todas sus claves de matriz.

+0

Si no agrega el [], php sólo utilizará criterios = tema, y ​​no hará caso del "miembro" –

+0

Véase también la respuesta a esta pregunta: http://stackoverflow.com/questions/6243051/how-to -pass-un-array-dentro-de-cadena de consulta –

+1

Para aclarar, Python no le importa si los [] '' s 'están ahí: lo convertirá correctamente independientemente. Pero sí, PHP (y tal vez otros idiomas?) Le importa, por lo que si usted tiene una dependencia externa en tales sistemas, lo mejor es dejar el [] '' s '... sólo se ve raro en Python. – CSTobey

10

Se puede utilizar una lista de pares clave-valor (tuplas):

>>> urllib.urlencode([('criterias[]', 'member'), ('criterias[]', 'issue')]) 
'criterias%5B%5D=member&criterias%5B%5D=issue' 
+0

Lástima que esta es la única manera. pero resolvió el problema. – Ikke

+0

Bueno, es muy fácil escribir una función que transforma el dict con listas en una lista de tuplas. –

+0

sólo una nota para otros, para generar la cadena urlencoded directamente desde un diccionario regular, todo lo que tiene que hacer es 'urllib.urlencode (d.Items())' – dlrust

2

Listcomp de valores:

>>> criterias = ['member', 'issue'] 
>>> urllib.urlencode([('criterias[]', i) for i in criterias]) 
'criterias%5B%5D=member&criterias%5B%5D=issue' 
>>> 
2

Para abstracto esto a trabajar para cualquier diccionario de parámetros y convertirlo en una lista de tuplas:

import urllib 

def url_encode_params(params={}): 
    if not isinstance(params, dict): 
     raise Exception("You must pass in a dictionary!") 
    params_list = [] 
    for k,v in params.items(): 
     if isinstance(v, list): params_list.extend([(k, x) for x in v]) 
     else: params_list.append((k, v)) 
    return urllib.urlencode(params_list) 

que ahora debería funcionar tanto para el ejemplo anterior como para un diccionario con algunas cadenas a y algunas matrices como valores:

criterias = ['member', 'issue'] 
params = { 
    'criterias[]': criterias, 
} 
url_encode_params(params) 
>>'criterias%5B%5D=member&criterias%5B%5D=issue' 
Cuestiones relacionadas