tutorial lenguaje instalar descargar python

python - lenguaje - Obtenga un dictado de todas las variables actualmente en alcance y sus valores



python tutorial (5)

Considera este fragmento:

globalVar = 25 def myfunc(paramVar): localVar = 30 print "Vars: {globalVar}, {paramVar}, {localVar}!".format(**VARS_IN_SCOPE) myfunc(123)

Donde VARS_IN_SCOPE es el dict que estoy globalVar que contendría globalVar , paramVar y localVar , entre otras cosas.

Me gustaría básicamente poder hacer referencia a todas las variables que están actualmente dentro del alcance dentro de la cadena. Por lo tanto, la salida esperada sería:

Vars: 25, 123, 30

Puedo lograr esto pasando **dict(globals().items() + locals().items()) a format() . ¿Esto siempre es correcto o hay algunos casos de esquina que esta expresión manejaría incorrectamente?

Reescrito para aclarar la pregunta.


¿Esto hace lo que pretendías?

d = dict(globals()) d.update(locals())

Si leo la documentación correctamente, crea una copia del dict global, luego sobrescribe los duplicados e inserta nuevas entradas del dict locals() ya que los locals() deberían tener preferencia dentro de su alcance, de todos modos).

No he tenido suerte en obtener una función adecuada para devolver el diccionario completo de variables en el alcance de la función de llamada . Aquí está el código (solo utilicé pprint para formatear la salida muy bien para SO):

from pprint import * def allvars_bad(): fake_temp_var = 1 d = dict(globals()) d.update(locals()) return d def foo_bad(): x = 5 return allvars_bad() def foo_good(): x = 5 fake_temp_var = "good" d = dict(globals()) d.update(locals()) return d pprint (foo_bad(), width=50) pprint (foo_good(), width=50)

y la salida:

{''PrettyPrinter'': <class pprint.PrettyPrinter at 0xb7d316ec>, ''__builtins__'': <module ''__builtin__'' (built-in)>, ''__doc__'': None, ''__file__'': ''temp.py'', ''__name__'': ''__main__'', ''__package__'': None, ''allvars_bad'': <function allvars_bad at 0xb7d32b1c>, ''d'': <Recursion on dict with id=3084093748>, ''fake_temp_var'': 1, ''foo_bad'': <function foo_bad at 0xb7d329cc>, ''foo_good'': <function foo_good at 0xb7d32f0c>, ''isreadable'': <function isreadable at 0xb7d32c34>, ''isrecursive'': <function isrecursive at 0xb7d32c6c>, ''pformat'': <function pformat at 0xb7d32bc4>, ''pprint'': <function pprint at 0xb7d32b8c>, ''saferepr'': <function saferepr at 0xb7d32bfc>} {''PrettyPrinter'': <class pprint.PrettyPrinter at 0xb7d316ec>, ''__builtins__'': <module ''__builtin__'' (built-in)>, ''__doc__'': None, ''__file__'': ''temp.py'', ''__name__'': ''__main__'', ''__package__'': None, ''allvars_bad'': <function allvars_bad at 0xb7d32b1c>, ''d'': <Recursion on dict with id=3084093884>, ''fake_temp_var'': ''good'', ''foo_bad'': <function foo_bad at 0xb7d329cc>, ''foo_good'': <function foo_good at 0xb7d32f0c>, ''isreadable'': <function isreadable at 0xb7d32c34>, ''isrecursive'': <function isrecursive at 0xb7d32c6c>, ''pformat'': <function pformat at 0xb7d32bc4>, ''pprint'': <function pprint at 0xb7d32b8c>, ''saferepr'': <function saferepr at 0xb7d32bfc>, ''x'': 5}

Tenga en cuenta que en el segundo resultado, hemos sobrescrito fake_temp_var , y x está presente; el primer resultado solo incluía los vars locales dentro del alcance de allvars_bad .

Por lo tanto, si desea acceder al alcance completo de la variable, no puede colocar locals () dentro de otra función.

Sospeché que había algún tipo de objeto de marco, simplemente no sabía dónde buscarlo.

Esto funciona según su especificación, creo:

def allvars_good(offset=0): frame = sys._getframe(1+offset) d = frame.f_globals d.update(frame.f_locals) return d def foo_good2(): a = 1 b = 2 return allvars_good()

->

{''PrettyPrinter'': <class pprint.PrettyPrinter at 0xb7d6474c>, ''__builtins__'': <module ''__builtin__'' (built-in)>, ''__doc__'': None, ''__file__'': ''temp.py'', ''__name__'': ''__main__'', ''__package__'': None, ''a'': 1, ''allvars_bad'': <function allvars_bad at 0xb7d65b54>, ''allvars_good'': <function allvars_good at 0xb7d65a04>, ''b'': 2, ''foo_bad'': <function foo_bad at 0xb7d65f44>, ''foo_good'': <function foo_good at 0xb7d65f7c>, ''foo_good2'': <function foo_good2 at 0xb7d65fb4>, ''isreadable'': <function isreadable at 0xb7d65c6c>, ''isrecursive'': <function isrecursive at 0xb7d65ca4>, ''pformat'': <function pformat at 0xb7d65bfc>, ''pprint'': <function pprint at 0xb7d65bc4>, ''saferepr'': <function saferepr at 0xb7d65c34>, ''sys'': <module ''sys'' (built-in)>}


La interpolación en cuerdas funciona de la manera más simple posible. Solo enumera tus variables. Python comprueba locales y globales por ti.

globalVar = 25 def myfunc(paramVar): localVar = 30 print "Vars: %d, %d, %d!" % ( globalVar, paramVar, localVar ) myfunc(123)


La mejor manera de fusionar dos dictados como lo estás haciendo (con los locales anulando a los globales) es dict(globals(), **locals()) .

Lo que falta en el enfoque de fusionar globales y locales es (a) construcciones internas (me imagino que es deliberado, es decir, no piensas en construcciones como "variables" ... pero, PODRÍAN serlo, si así lo eliges! -), y (b) si está en una función anidada , cualquier variable que sea local para adjuntar funciones (no es realmente una buena forma de obtener un dict con todas esas , más - solo aquellas a las que se accede explícitamente en la función anidada, es decir, "gratuitas sus variables ", sobreviven como células en un cierre, de todos modos).

Me imagino que estos problemas no son un gran problema para su uso previsto, pero mencionó "casos de esquina" ;-). Si necesita cubrirlos, hay formas de obtener integradas (eso es fácil) y (no tan fácil) todas las celdas (variables de las funciones adjuntas que menciona explícitamente en la función anidada - thefunction.func_code.co_freevars to obtener los nombres, thefunction.func_closure para obtener las celdas, cell_contents en cada celda para obtener su valor). (¡Pero recuerde, esas solo serán variables de las funciones adjuntas a las que se accede explícitamente en el código de su función anidada!).


Usted podría hacer su propio:

allvars = dict() allvars.update(globals()) allvars.update(locals())

o combine las primeras dos líneas:

allvars = dict(globals()) allvars.update(locals())


globalVar = 25 def myfunc(paramVar): localVar = 30 all_vars = locals.copy() all_vars.update(globals()) print "Vars: {globalVar}, {paramVar}, {localVar}!".format(all_vars) myfunc(123)