Python 2.5 имеет эквивалент команды верхнего уровня Tcl?

Есть ли в Python эквивалент команды Tcl верхнего уровня? Для тех, кто не знает, команда "uplevel" позволяет запускать код в контексте вызывающей стороны. Вот как это может выглядеть в python:

def foo():
    answer = 0
    print "answer is", answer # should print 0
    bar()
    print "answer is", answer # should print 42


def bar():
    uplevel("answer = 42")

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

2 ответа

Решение

В общем, то, что вы спрашиваете, невозможно (с результатами, которые вы, несомненно, ожидаете). Например, представьте, что "любой код" x = 23, Будет ли это добавить новую переменную x к набору локальных переменных вашего вызывающего, если вы нашли черный магический способ выполнить этот код "в вызывающем"? Нет, не будет - критическая оптимизация, выполняемая компилятором Python, заключается в том, чтобы определить раз и навсегда, когда def выполняет точный набор локальных переменных (все голые имена, которые присваиваются или иным образом связываются в теле функции), и превращает каждый доступ и установку к этим голым именам в очень быструю индексацию в стеке. (Вы можете систематически победить эту решающую оптимизацию, например, имея exec '' в начале каждого возможного звонящего - и, как следствие, увидите падение производительности вашей системы через пол).

За исключением присвоения местным именам вызывающего абонента, exec thecode in thelocals, theglobals может делать примерно то, что вы хотите, и inspect Модуль позволяет вам получить локальные и глобальные значения вызывающего абонента в полудумном виде (в той степени, в которой глубокая черная магия - которая заставила бы меня отправиться по почте на любого коллегу, предполагая, что он будет выполнен в производственном коде) - когда-либо может быть удостоена чести незаслуженная похвала, называя это "полуразумным", то есть;-).

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

Написана ли сторонняя библиотека на Python? Если да, вы можете переписать и перепривязать функцию "foo" во время выполнения с вашей собственной реализацией. Вот так:

import third_party

original_foo = third_party.foo
def my_foo(*args, **kwds):
    # do your magic...
    original_foo(*args, **kwds)
third_party.foo = my_foo

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

Другие вопросы по тегам