Эта проблема несколько обсуждается в списке ошибок Python3 . В конечном счете, чтобы получить это поведение, вам нужно сделать:
def foo():
ldict = {}
exec("a=3",globals(),ldict)
a = ldict['a']
print(a)
И если вы проверите документацию Python3 на exec
, вы увидите следующее примечание:
Локали по умолчанию действуют, как описано для функции
blockquote>locals()
ниже: не следует пытаться модифицировать словарь локальных файлов по умолчанию. Передайте явный словарь locals, если вам нужно увидеть эффекты кода на локалях после возврата функции exec ().Обратившись к к определенному сообщению в отчете об ошибке , Георг Брандл говорит:
Для изменения локалей функции «на лету» невозможно без нескольких последствий: обычно локаторы функций не хранятся в словаре, а массиве, индексы которого определяются во время компиляции из известных локалей. Это сталкивается, по крайней мере, с новыми локалями, добавленными exec. Старая инструкция exec обошла это, потому что компилятор знал, что если в функции произошел exec без globals / locals args, это пространство имен будет «неоптимизировано», то есть не будет использовать массив locals. Поскольку exec () теперь является нормальной функцией, компилятор не знает, к чему «exec» может быть привязан, и поэтому не может быть обработан специально.
blockquote>Акцент мой.
Таким образом, суть в том, что Python3 может лучше оптимизировать использование локальных переменных с помощью not , позволяя это поведение по умолчанию.
И ради полноты, как упомянутый в комментариях выше, этот работает , как и ожидалось в Python 2.X:
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> def f(): ... a = 1 ... exec "a=3" ... print a ... >>> f() 3
Глядя на то, что вы можете сделать с потоком, вы видите, что у него есть метод stop. Тем не менее, вы также увидите, что это устарело. Изучение объяснения его устаревания проясняет:
* @deprecated This method is inherently unsafe. Stopping a thread with
* Thread.stop causes it to unlock all of the monitors that it
* has locked (as a natural consequence of the unchecked
* <code>ThreadDeath</code> exception propagating up the stack). If
* any of the objects previously protected by these monitors were in
* an inconsistent state, the damaged objects become visible to
* other threads, potentially resulting in arbitrary behavior. Many
* uses of <code>stop</code> should be replaced by code that simply
* modifies some variable to indicate that the target thread should
* stop running. The target thread should check this variable
* regularly, and return from its run method in an orderly fashion
* if the variable indicates that it is to stop running. If the
* target thread waits for long periods (on a condition variable,
* for example), the <code>interrupt</code> method should be used to
* interrupt the wait.
* For more information, see
* <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
Следовательно, у вас должна быть проверка в вашем потоке, как у вас: ваша переменная end
. Обновите его в блоке finally, и ваш поток естественным образом достигнет конца своего выполнения.