2010-02-23 11 views
6

PHP tiene una función llamada extract() que toma una matriz asociativa como argumento y crea variables locales de las claves cuyos valores están asignados a los valores de la clave. ¿Hay alguna manera de hacer esto en Python? Una búsqueda rápida en Google no me mostró de inmediato cómo. Sospecho que hay una forma con exec() pero sería bueno si hubiera alguna función para hacerlo por mí.¿Hay alguna forma de extraer un dict en Python en el espacio de nombres local?

+1

"Otro idioma puede hacerlo" rara vez es una buena razón para implementar una funcionalidad específica. –

+0

Esta no es una característica "imprescindible" para mí, solo creo que es bastante ingeniosa para las funciones que toman ** kwargs. – Kevin

+2

Si sabes estáticamente los nombres que estás recibiendo con kwargs y puedes escribirlos en el cuerpo de tu función, no estarías usando '** kwargs'. –

Respuesta

5

Dado que es not safe modificar el dict que los locales() devuelve

>>> d={'a':6, 'b':"hello", 'c':set()} 
>>> exec '\n'.join("%s=%r"%i for i in d.items()) 
>>> a 
6 
>>> b 
'hello' 
>>> c 
set([]) 

Pero el uso ejecutivo de este tipo es feo. Debe rediseñar para que no necesite agregar dinámicamente a su espacio de nombres local

Editar: Consulte las reservas de Mike sobre el uso de repr en los comentarios.

>>> d={'a':6, 'b':"hello", 'c':set()} 
>>> exec '\n'.join("%s=d['%s']"%(k,k) for k in d) 
>>> id(d['c']) 
3079176684L 
>>> id(c) 
3079176684L 
+0

Gracias, usaré esto.Mencioné anteriormente que NO NECESITO esta funcionalidad, solo creo que es bueno tenerla. – Kevin

+1

Aunque no creo que nadie * realmente * necesite esta funcionalidad, una forma de rediseñar su código sería pasar el dict a una función con ** kwargs, donde el dict se desempaquetará limpiamente en el espacio de nombres local. –

+0

Este código está roto. Si hicieras esto, harías referencia al dict en sí mismo, no extraerá los informes de los objetos, lo que no funciona en el caso general. Por ejemplo, creaste un nuevo conjunto en lugar de usar el pasado y si te hubiera pasado un tipo diferente, como uno que hice sin un 'repr' útil, estarías en el arroyo. –

-1

Encontré un question similar que ha sido respondido en SO. La respuesta aceptada sugiere rodar su propio extracto equivalente para python.

3

Probar:

locals().update(my_dict) 

EDIT:

gnibbler ha hecho un punto muy válido que los locales no deben ser modificados (marque: http://docs.python.org/library/functions.html#locals). Aún así, Python Docs no dice que no es seguro, solo dice que los cambios en los locales pueden no afectar los valores de las variables. Antes de responder la pregunta que probé en mi IDLE 2.6 de Python, la actualización de locals realmente funciona, tanto en alcance global como dentro de una función. Es por eso que no borro mi respuesta, pero en su lugar agrego una advertencia que podría funcionar bajo ciertas circunstancias (¿específicas de la plataforma?), Pero no está garantizada.

+4

No es seguro realizar modificaciones en 'locals()' http://docs.python.org/library/functions.html#locals –

+0

No lo sé, ¿tiene algún vínculo que respalde esto? EDIT: encontré aquí que los locals() son de solo lectura, que no es el caso en el shell IDLE 2.6 ... –

+0

No es sabio, pero es suficiente para un uso casual. –

-1

locales Modificación() dict podría haber sido una solución, pero docs decir, http://docs.python.org/library/functions.html#

Nota El contenido de este diccionario no debe ser modificado; los cambios pueden no afectar los valores locales y variables gratuitas utilizadas por el intérprete .

así que la pregunta es ¿por qué incluso lo necesita? puede haber mejores formas de lograr eso sea lo que sea que intentes lograr.

¿Por qué no puedes acceder directamente a dict o asignarles variables?

Cuestiones relacionadas