Eval solo funciona si defino el alcance fuera de la llamada.
Tengo el siguiente código simplificado:
scope = locals()
for batch in stream:
for row in batch.results:
writer.writerow([eval(pf, scope) for pf in process_fields])
Guarda en un archivo csv
el contenido de los diferentes campos del objeto row
(objeto GoogleAdsRow
).
Funciona bien, pero falla si no uso la variable scope
, sino la función locals()
directamente:
for batch in stream:
for row in batch.results:
writer.writerow([eval(pf, locals()) for pf in process_fields])
Devuelve:
NameError: el nombre 'account' no está definido
donde account
es uno de los process_fields
.
Por lo tanto, asumo que es porque la función eval
no encuentra la variable, pero no entiendo por qué un cambio tan pequeño crea ese problema.
davy.ai
La diferencia entre el uso de
scope
ylocals()
es quescope
se refiere al diccionario de variables locales en el punto donde se ejecutascope = locals()
. Esto significa que cualquier variable definida después de ese punto no estará disponible enscope
.Por otro lado,
locals()
es una función que devuelve un diccionario de las variables locales actuales. Esto incluye cualquier variable definida después de que se llame alocals()
, pero también incluye algunas otras variables que no son relevantes para el contexto actual.Cuando se llama a
eval
conlocals()
, se intenta evaluarpf
en el contexto del diccionario devuelto porlocals()
. Este diccionario contiene muchas variables que no son relevantes para el contexto actual y no incluye ninguna variable definida después de que se llame alocals()
.Esta es la razón por la que obtienes un
NameError
cuando usaslocals()
. La variableaccount
no está definida en el diccionario devuelto porlocals()
, por lo queeval
no puede encontrarla.Para evitar este problema, puedes usar
scope
, que solo incluye las variables relevantes, o puedes crear un nuevo diccionario que incluya todas las variables relevantes utilizando la funciónlocals()
en el punto donde se definen las variables relevantes. Por ejemplo:Esto crea un nuevo diccionario
local_vars
al inicio de cada iteración del bucle que incluye todas las variables definidas hasta ese punto. De esta manera,eval
puede encontrar todas las variables relevantes sin incluir ninguna irrelevante.