Как получить/установить локальные переменные функции (извне) в Python?

Если у меня есть функция (в Python 2.5.2), например:

def sample_func():
    a = 78
    b = range(5)
    #c = a + b[2] - x

Мои вопросы:

  • Как получить локальные переменные (a, b) функции извне без с помощью locals() внутри функции? (вид отражения)
  • Можно ли установить локальную переменную (например, x) извне, чтобы работа с комментариями работала? (Я знаю, это звучит странно).

Спасибо заранее.

ИЗМЕНИТЬ

Каждый запрашивает прецедент. Но это странная ситуация. (Не обвиняйте меня, я не создал его). Вот сценарий:

  • У меня есть зашифрованный исходный файл python, содержащий функцию python.
  • Модуль расширения C расшифровывает его и создает эту функцию в памяти.
  • Основная программа python сначала вызывает расширение C с зашифрованным расположением файла.
  • Затем основная программа вызывает функцию, которая была встроена в память (с расширением C)
  • Но основная программа должна знать локальные переменные этой функции (не спрашивайте меня, почему это было не я).
  • По какой-то (чертовой) причине основная программа должна также установить переменную (самое странное)

Ответ 1

Нет. Функция, которая не запускается, не имеет локалей; это просто функция. Просьба о том, как изменить локаль функции, когда она не работает, напоминает запрос о том, как изменить кучу программы, когда она не работает.

Вы можете изменить константы, хотя, если вы действительно этого хотите.

def func():
    a = 10
    print a

co = func.func_code
modified_consts = list(co.co_consts)
for idx, val in enumerate(modified_consts):
    if modified_consts[idx] == 10: modified_consts[idx] = 15

modified_consts = tuple(modified_consts)

import types
modified_code = types.CodeType(co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, co.co_code, modified_consts, co.co_names, co.co_varnames, co.co_filename, co.co_name, co.co_firstlineno, co.co_lnotab)
modified_func = types.FunctionType(modified_code, func.func_globals)
# 15:
modified_func()

Это взломать, потому что нет способа узнать, какая константа в co.co_consts есть; для этого используется значение дозорного. В зависимости от того, достаточно ли вы ограничить свои варианты использования, этого может быть достаточно.

Ответ 2

Я не уверен, что ваш прецедент, но это может работать лучше, чем класс. Вы можете определить метод __call__, чтобы класс работал как функция.

например:.

>>> class sample_func(object):
...     def __init__(self):
...         self.a = 78
...         self.b = range(5)
...     def __call__(self):
...         print self.a, self.b, self.x
... 
>>> f = sample_func()
>>> print f.a
78
>>> f.x = 3
>>> f()
78 [0, 1, 2, 3, 4] 3

(это основано на вашем примере с игрушкой, поэтому код не имеет большого смысла. Если вы дадите более подробную информацию, мы сможем предоставить лучший совет)

Ответ 3

Локальные функции изменяются всякий раз, когда функция запускается, поэтому мало смысла обращаться к ним, пока функция не запущена.

Ответ 4

Не уверен, что это то, что вы имеете в виду, но поскольку функции являются объектами в Python, вы можете привязывать переменные к объекту функции и обращаться к ним из "снаружи":

def fa():
    print 'x value of fa() when entering fa(): %s' % fa.x
    print 'y value of fb() when entering fa(): %s' % fb.y
    fa.x += fb.y
    print 'x value of fa() after calculation in fa(): %s' % fa.x
    print 'y value of fb() after calculation in fa(): %s' % fb.y
    fa.count +=1


def fb():
    print 'y value of fb() when entering fb(): %s' % fb.y
    print 'x value of fa() when entering fa(): %s' % fa.x
    fb.y += fa.x
    print 'y value of fb() after calculation in fb(): %s' % fb.y
    print 'x value of fa() after calculation in fb(): %s' % fa.x
    print 'From fb() is see fa() has been called %s times' % fa.count


fa.x,fb.y,fa.count = 1,1,1

for i in range(10):
    fa()
    fb()

Прошу извинить меня, если я ужасно ошибаюсь... Я сам начинающий программист и программист...

Ответ 5

Ожидание переменной в функции, которая должна быть установлена ​​внешней функцией ПЕРЕД вызовом этой функции, является такой плохой дизайн, что единственным реальным ответом, который я могу порекомендовать, является изменение дизайна. Функция, которая ожидает, что ее внутренние переменные будут установлены до ее запуска, бесполезна.

Итак, реальный вопрос, который вы зададите, - это то, почему эта функция ожидает, что x будет определяться вне функции? Использует ли исходная программа, для которой функция используется, чтобы установить глобальную переменную, к которой эта функция имела бы доступ? Если это так, то это может быть так же просто, как предложить оригинальным авторам этой функции, что они вместо этого позволяют передавать x в качестве аргумента. Простое изменение в вашей функции выборки обеспечит работу кода в обеих ситуациях:

def sample_func(x_local=None):
  if not x_local:
    x_local = x
  a = 78
  b = range(5)
  c = a + b[2] - x_local

Это позволит функции принимать параметр из вашей основной функции так, как вы хотите ее использовать, но она не будет разрушать другую программу, поскольку она все равно будет использовать глобально определенный x, если функции не заданы никакие аргументы.