Python 2.5 имеет эквивалент команды верхнего уровня Tcl? - PullRequest
2 голосов
/ 25 сентября 2010

Есть ли в 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 ]

3 голосов
/ 25 сентября 2010

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

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

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

1 голос
/ 25 сентября 2010

Сторонняя библиотека написана на 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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...