Я использую Boto для доступа к Amazon S3. А для загрузки файлов я могу назначить функцию обратного вызова. Проблема в том, что я не могу получить доступ к необходимым переменным из этой функции обратного вызова, пока я не сделаю их глобальными. С другой стороны, если я сделаю их глобальными, они будут глобальными и для всех других задач Celery (до тех пор, пока я не перезапущу Celery), поскольку загрузка файла выполняется из задачи Celery.
Вот функция, которая загружает файл JSON с информацией о ходе преобразования видео.
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")
А вот 2 функции обратного вызова для загрузки кадров, сгенерированных ffmpeg во время преобразования видео, и файл JSON с информацией о ходе выполнения.
# 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
Теоретически, я мог бы передать переменную uploading_frame в функцию upload_json, но она не попала бы в json_upload_callback, поскольку она выполняется Boto.
На самом деле, я мог бы написать что-то вроде этого.
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
Что, однако, не позволяет вам редактировать значение из функции, просто позволяет вам прочитать значение.
def myfunc():
stuff = 17
def lfun(arg):
print "got arg", arg, "and stuff is", stuff
return lfun
my_function = myfunc()
my_function("hello")
Это работает.
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")
И это дает UnboundLocalError: локальную переменную 'stuff', на которую ссылаются перед присваиванием.
Спасибо.