Как создать модальное всплывающее окно для подтверждения добавления в корзину на странице просмотра в magento 1.9

Как мне вызвать функцию или как ее обернуть, чтобы, если она занимает больше 5 секунд, скрипт отменяет ее?

Я отправил gist , который решает этот вопрос / проблему с декоратором и threading.Timer. Здесь он с разбивкой.

Импорт и настройки для совместимости

Он был протестирован с Python 2 и 3. Он также должен работать под Unix / Linux и Windows.

Сначала импорт. Эти попытки сохранить код совместимым независимо от версии Python:

from __future__ import print_function
import sys
import threading
from time import sleep
try:
    import thread
except ImportError:
    import _thread as thread

Использовать независимый от версии код:

try:
    range, _print = xrange, print
    def print(*args, **kwargs): 
        flush = kwargs.pop('flush', False)
        _print(*args, **kwargs)
        if flush:
            kwargs.get('file', sys.stdout).flush()            
except NameError:
    pass

Теперь мы импортировали наши функции из стандартной библиотеки.

exit_after decorator

Далее нам нужна функция для завершения main() из дочернего потока:

def quit_function(fn_name):
    # print to stderr, unbuffered in Python 2.
    print('{0} took too long'.format(fn_name), file=sys.stderr)
    sys.stderr.flush() # Python 3 stderr is likely buffered.
    thread.interrupt_main() # raises KeyboardInterrupt

И вот сам декоратор :

def exit_after(s):
    '''
    use as decorator to exit process if 
    function takes longer than s seconds
    '''
    def outer(fn):
        def inner(*args, **kwargs):
            timer = threading.Timer(s, quit_function, args=[fn.__name__])
            timer.start()
            try:
                result = fn(*args, **kwargs)
            finally:
                timer.cancel()
            return result
        return inner
    return outer

Использование

И вот использование, которое напрямую отвечает на ваш вопрос об окончании через 5 секунд!:

@exit_after(5)
def countdown(n):
    print('countdown started', flush=True)
    for i in range(n, -1, -1):
        print(i, end=', ', flush=True)
        sleep(1)
    print('countdown finished')

Демонстрация:

>>> countdown(3)
countdown started
3, 2, 1, 0, countdown finished
>>> countdown(10)
countdown started
10, 9, 8, 7, 6, countdown took too long
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 11, in inner
  File "", line 6, in countdown
KeyboardInterrupt

Второй вызов функции не будет завершен, вместо этого процесс должен выйти с трассировкой!

KeyboardInterrupt не всегда останавливает спальный поток

Обратите внимание, что спящий режим не всегда прерывается прерыванием клавиатуры на Python 2 в Windows, например:

@exit_after(1)
def sleep10():
    sleep(10)
    print('slept 10 seconds')

>>> sleep10()
sleep10 took too long         # Note that it hangs here about 9 more seconds
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 11, in inner
  File "", line 3, in sleep10
KeyboardInterrupt

, и он не может прервать работу кода в расширениях, если он явно не проверяет наличие PyErr_CheckSignals(), см. Cython, Python и KeyboardInterrupt игнорируются

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

] Как мне вызвать функцию или как ее обернуть, чтобы, если она занимает больше 5 секунд, скрипт отменяет ее и делает Что-то еще?

Чтобы поймать его и сделать что-то еще, вы можете поймать KeyboardInterrupt.

>>> try:
...     countdown(10)
... except KeyboardInterrupt:
...     print('do something else')
... 
countdown started
10, 9, 8, 7, 6, countdown took too long
do something else
0
задан EzLo 15 January 2019 в 10:08
поделиться