Есть ли способ сделать больше работы после заявления возврата?

Мне было немного любопытно, если бы я мог больше работать в функции после возвращения результата. В основном я создаю сайт, используя фреймворк pyramid (который просто кодируется в python) после того, как я обрабатываю входные данные, которые возвращаю переменные для рендеринга страницы, но иногда я хочу сделать больше работы после того, как я сделаю страницу.

Например, вы приходите на мой сайт и обновляете свой профиль, и все, о чем вы заботитесь, – это его успех, поэтому я выводил сообщение с сообщением «успех!». но после этого я хочу принять ваше обновление и обновить журналы активности, что вы делаете, обновить потоки активности ваших друзей и т. д. Сейчас я делаю все это, прежде чем возвращать статус результата, который вас волнует, Любопытно, если я смогу это сделать после того, как пользователи быстрее получат ответы.

Я делал многопроцессорную обработку до и в худшем случае, я мог бы просто разветвить поток для выполнения этой работы, но если бы был способ выполнить работу после оператора return, это было бы проще.

пример:

def profile_update(inputs): #take updates and update the database return "it worked" #do maintainence processing now.. 

  • Как использовать try .. кроме или if ... else для проверки ввода пользователя?
  • как проверить, является ли файл каталогом или обычным файлом в python?
  • Python: Где freeze.py?
  • разбор сложного логического выражения в pyparsing в двоичном древе
  • Умножение Python (2.x) не происходит должным образом
  • Как превратить список строк в сложные числа в python?
  • Запуск сценариев Python внутри Android Studio
  • os.walk () полоски польский символ
  • 5 Solutions collect form web for “Есть ли способ сделать больше работы после заявления возврата?”

    Нет, к сожалению, как только вы нажмете на оператор return , вы вернетесь из функции / метода (либо с возвращаемым значением, либо без него).

    Из документов для возврата :

    return возвращает текущий вызов функции с списком выражений (или None) в качестве возвращаемого значения.

    Вы можете посмотреть в функции генератора и инструкцию yield , это способ вернуть значение из функции и продолжить обработку и подготовить другое значение, которое будет возвращено, когда функция будет вызвана в следующий раз.

    Почему вы не используете контекстный менеджер ? Это в основном делает именно то, что вы хотите.

    Вот канонический пример из документов Python.

     from contextlib import contextmanager @contextmanager def tag(name): print "<%s>" % name yield print "</%s>" % name 

    Поэтому для вашей функции вы просто выполните:

     @contextmanager def profile_update(inputs): #take updates and update the database yield "it worked" #do maintainence processing now.. 

    И чтобы назвать это, вы просто выполните:

     with profile_update(inputs) as result: #pre-yield and yield here # do whatever while in scope # as you move out of scope of with statement, post-yield is executed 

    EDIT: Я просто тестировал вещи, и получается, что с оператором yield функция все еще выполняется до конца. Вот глупый пример, который иллюстрирует суть и когда дела выполняются.

     def some_generator(lst): for elem in lst: yield elem lst[0] = "I WAS CHANGED POST-YIELD!!!!" >>> q = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> gen = some_generator(q) >>> for e in gen: ... print e, q 0 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 3 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 4 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 5 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 6 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 7 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 8 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 9 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print q ['I WAS CHANGED POST YIELD!!!', 1, 2, 3, 4, 5, 6, 7, 8, 9] 

    Преимущество контекстного менеджера состоит в том, что не требуется два next вызова, чтобы перейти на итерацию остановки (и более чистый синтаксис), но если вы хотите вернуть несколько значений или что-то еще, вы также можете сделать это таким образом, но вы можете видеть, что доходность post оператор фактически не вызывается до тех пор, пока генератор не остановит StopIteration при next вызове (цикл for заканчивается, когда он получает StopIteration )


    Если по какой-то причине вам требуется более высокая степень контроля, чем предложения @contextmanager , вы также можете определить класс с __enter__ и __exit__ :

     class MyContextClass(object): # ... def __enter__(self): # do some preprocessing return some_object def __exit__(self, exc_type, exc_value, traceback): # do some post processing # possibly do some processing of exceptions raised within the block if exc_type == MyCustomErrorType: return True #don't propagate the error 

    Вы можете выполнить некоторую работу после возвращения, если вы вернетесь из блока try, блок finally все равно будет выполнен, например:

     def fun(): try: return finally: print "Yay! I still got executed, even though my function has already returned!" 

    Цитирование документов :

    Когда return передает управление из инструкции try с предложением finally, это предложение finally выполняется до того, как он действительно покинет функцию.

    Нет, возврат возвращает значение вызывающему абоненту и останавливается.

    Если вызывающий (-ы) также находятся под вашим контролем (а не частью структуры пирамиды), вы можете изменить profile_updates чтобы они выглядели следующим образом:

     def profile_update(inputs): #take updates and update the database def post_processing_task(): #do maintainence processing now.. return ("it worked", post_processing_task) 

    А затем закодировать вызывающего абонента на ожидание пары (response, task) , а не просто ответ. Он может сделать что-то сразу с частью response (сообщить об этом пользователю), а затем вызвать task() для обработки пост-обработки.

    Это позволяет profile_update определять, какой код необходимо выполнить впоследствии (и сохранить эти данные скрытыми и инкапсулированными с более высокого уровня), но позволяет более высокому уровню определять поток передачи ответа пользователю, а затем выполнять пост-обработку в фон.

    Можно обмануть структуру try-except-finally . Пример:

     def function(): try: #do some stuff here return x except Exception: #do something when an error occures finally: #do here whatever you wanna do after return 

    Обратите внимание, что оператор finally будет выполнен, даже если было обнаружено исключение.

    Interesting Posts

    Почему 4 <'3' возвращает True в Python 2?

    Найти элемент по тексту с помощью XPath в ElementTree

    Как проверить URL-адрес либо ссылку на веб-страницу, либо ссылку на файл в python

    Оператор 'is' ведет себя неожиданно с не кэшированными целыми числами

    Сканирование QR-кода через zbar и Raspicam modul

    Python matplotlib: память не выделяется при задании размера фигуры

    Механизм Python с NTLM получает AttributeError: экземпляр HTTPResponse не имеет атрибута '__iter__'

    Как запустить все тестовые тесты Python в каталоге?

    Как печатать переменную внутри кавычек?

    Каков 5-значный буквенно-цифровой идентификатор в URL-адресе reddit?

    Быстрая интерполяция регулярно сэмплированных 3D-данных с разными интервалами по x, y и z

    Переименуйте несколько файлов в каталог в Python

    Использование модуля многопроцессорности python для ввода-вывода с pygame на Mac OS 10.7

    KenKen puzzle addends: REDUX A (исправленный) нерекурсивный алгоритм

    Как я могу превратить список в массив в python?

    Python - лучший язык программирования в мире.