es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    La diferencia entre el uso de scope y locals() es que scope se refiere al diccionario de variables locales en el punto donde se ejecuta scope = locals(). Esto significa que cualquier variable definida después de ese punto no estará disponible en scope.

    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 a locals(), pero también incluye algunas otras variables que no son relevantes para el contexto actual.

    Cuando se llama a eval con locals(), se intenta evaluar pf en el contexto del diccionario devuelto por locals(). 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 a locals().

    Esta es la razón por la que obtienes un NameError cuando usas locals(). La variable account no está definida en el diccionario devuelto por locals(), por lo que eval 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ón locals() en el punto donde se definen las variables relevantes. Por ejemplo:

    for batch in stream:
         for row in batch.results:
              local_vars = locals()
              writer.writerow([eval(pf, local_vars) for pf in process_fields])
    

    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.

Comments are closed.