Uso Boto para acceder a Amazon S3. Y para cargar archivos puedo asignar una función de devolución de llamada. El problema es que no puedo acceder a las variables necesarias desde esa función de devolución de llamada hasta que las hago globales. Por otro lado, si los hago globales, también serán globales para todas las demás tareas de Apio (hasta que reinicie Apio), ya que la carga del archivo se ejecuta desde una tarea de Apio.¿Cómo acceder (y editar) variables desde una función de devolución de llamada?
Aquí hay una función que carga un archivo JSON con información sobre el progreso de conversión de video.
def upload_json():
global current_frame
global path_to_progress_file
global bucket
json_file = Key(bucket)
json_file.key = path_to_progress_file
json_file.set_contents_from_string('{"progress": "%s"}' % current_frame,
cb=json_upload_callback, num_cb=2, policy="public-read")
Y aquí son 2 funciones de devolución de llamada para subir marcos generados por ffmpeg durante la conversión de vídeo y un archivo JSON con la información de progreso.
# Callback functions that are called by get_contents_to_filename.
# The first argument is representing the number of bytes that have
# been successfully transmitted from S3 and the second is representing
# the total number of bytes that need to be transmitted.
def frame_upload_callback(transmitted, to_transmit):
if transmitted == to_transmit:
upload_json()
def json_upload_callback(transmitted, to_transmit):
global uploading_frame
if transmitted == to_transmit:
print "Frame uploading finished"
uploading_frame = False
En teoría, podría pasar la variable uploading_frame a la función upload_json, pero no iba a llegar a json_upload_callback ya que es ejecutado por Boto.
De hecho, podría escribir algo como esto.
In [1]: def make_function(message):
...: def function():
...: print message
...: return function
...:
In [2]: hello_function = make_function("hello")
In [3]: hello_function
Out[3]: <function function at 0x19f4c08>
In [4]: hello_function()
hello
Lo cual, sin embargo, no le permite editar el valor de la función, simplemente le permite leer el valor.
def myfunc():
stuff = 17
def lfun(arg):
print "got arg", arg, "and stuff is", stuff
return lfun
my_function = myfunc()
my_function("hello")
Esto funciona.
def myfunc():
stuff = 17
def lfun(arg):
print "got arg", arg, "and stuff is", stuff
stuff += 1
return lfun
my_function = myfunc()
my_function("hello")
Y esto da un UnboundLocalError: variable local 'cosas' a las que se hace referencia antes de la asignación.
Gracias.
Su ejemplo no muestra cómo uploading_frame se utiliza, por lo que es difícil de entender por qué evento desea. Crear un ejemplo más simple sin ningún material relacionado con S3 que muestre más claramente el problema probablemente también ayude. – dkagedal