Использование set_timeout с API Sublime Text 3

Я пытаюсь использовать (как следует из названия) функцию set_timeout возвышенного текста 3 в плагине.
Насколько я понял, во многих случаях требуется использование лямбда-функции. Итак, я попробовал этот простой тест:

class SetTimeoutTestCommand(sublime_plugin.WindowCommand):
    def run(self):
        for x in range(1,10):
            sublime.set_timeout(lambda : print(x), 4000)

Поэтому я ожидал, что число будет печататься по одному с задержкой в ​​4 секунды между каждым. Как поясняется в Sublime 3 API:

Запускает обратный вызов в основном потоке после заданной задержки (в миллисекундах). Обратные вызовы с одинаковой задержкой будут выполняться в том порядке, в котором они были добавлены.

Но вместо этого у меня есть 9 '9', которые печатаются через 4 секунды. Таким образом, все "9" печатаются одновременно, основываясь на первой итерации цикла.
У вас есть идея, что я могу сделать, чтобы решить эту проблему?

Заранее спасибо !

Редактировать: я нашел это, которое работает (ну, которое печатает «9» 9 раз с задержкой в ​​​​1 секунду между каждым:

class SetTimeoutTestCommand(sublime_plugin.WindowCommand):
    def run(self):
        for x in range(1,10):
            sublime.set_timeout(lambda : print(x), x*1000)

Но проблема остается: он печатает только «9»....


person nobe4    schedule 27.11.2013    source источник


Ответы (2)


Чтобы печатать разные числа, измените скрипт вашего плагина на этот

class SetTimeoutTestCommand(sublime_plugin.WindowCommand):
    def run(self, edit):
        for x in range(1,10):
            sublime.set_timeout(lambda x=x: print(x), x*1000)

Потому что все лямбда-функции ссылаются на один и тот же x, и когда он выполняется, значение x достигает 9.

person Deck    schedule 30.11.2013
comment
Да, это работает, спасибо вам. В задании можно заменить на : lambda y=x: print(y) - person nobe4; 02.12.2013

Первое, что нужно понять, это то, что вызовы set_timeout возвращаются немедленно. То есть вы планируете выполнение всех функций печати за 1 секунду. Не в 1 секунду друг от друга. Основываясь на вашем редактировании, кажется, вы поняли это, но просто подумали, что я уточню.

Что касается всегда печати 9, все операторы печати ссылаются на одно и то же значение. Таким образом, даже когда запланирована первая печать, она ссылается на то же значение x, которое вы увеличиваете. К тому времени, когда печать действительно запускается (через 1 секунду), значение x равно 9. Таким образом, 9 печатается для каждого запланированного обратного вызова.

Надеюсь, что это проясняет некоторые вещи.

person skuroda    schedule 30.11.2013
comment
Хорошо, насколько я понимаю, лямбда-функция будет принимать последнее значение x, так как присваивания нет. Выполняя задание, значение заменяется на каждой итерации. У вас есть ссылка для получения дополнительной информации по этому вопросу? Спасибо =) - person nobe4; 02.12.2013
comment
Я не могу ничего придумать, хотя я уверен, что они где-то там. Полезно (в целом) понимать, когда вещи передаются по ссылке, а когда по значению. - person skuroda; 05.12.2013