Как изменить переменные другой области? - PullRequest
1 голос
/ 15 декабря 2010

Собственно, я пытаюсь сделать следующее: Некоторые функции mutator принимают локальную область видимости других функций, используя locals()

def mutator(locals):
    locals['n'] = 10
    locals['l'].append(10)

def f():
    n = 1
    l = [1]
    mutator(locals())
    print(n,l) # >>> 1, [1,10]

f(None)

, и это работает, как и ожидалось: я смог изменить содержимое изменяемого списка, ноне удалось «перепривязать» другой неизменный int к тому же имени.

В настоящее время я вижу некоторые варианты:

  • eval(), exec() & Co
  • Играть со стековыми кадрами и локальными переменными в mutator()
  • Хранить такие переменные в dict: не очень удобно, но, вероятно, лучше всего

Ограничение: цельфункция f() может содержать только один вызов функции, возможно, с аргументами, и эта функция должна иметь возможность изменять значения в f() текущей области видимости.

Итак ... есть ли способ повторно ввести значение переменной (привязать другой объект) во время выполнения?Я не верю, что нет хорошего трюка, чтобы достичь этого!


Вот пример того, чего я пытаюсь достичь:

def view(request): # Yes, that's Django!
    q = MyModel.objects.all()

    data = { 'some_action': True, 'items_per_page': 50 } # defaults. Mutators can change this
    mutators.launch(locals(), data ) # Launch mutators that may want to narrow the QuerySet

    if data['some_action']: # do something useful if no mutator has disabled it
          ...

    # paginate using data['items_per_page']

Я не хочуиспользовать data dict здесь: возможность изменять их как локальные переменные была бы намного лучше и приятнее.Обратите внимание, что q Объект QuerySet является изменяемым, и мутаторы могут изменять его содержимое.

Ответы [ 2 ]

3 голосов
/ 15 декабря 2010
class AttributeCollection(object):
    pass
shared_settings= AttributeCollection()
# now improvise
shared_settings.temperature= 30
shared_settings.samples= []
# etc

Передайте это shared_settings или сделайте его глобальным, и установите его атрибуты так, как вам хочется.

Видите ли, locals() функции - это просто пространство имен, предназначенное (и оптимизированное для него) для манипулирования внутри этой функции (и во время работы этой функции). Используйте другое пространство имен (по моему предложению, объект shared_settings) в качестве общей игровой площадки для вашего кода.

0 голосов
/ 15 декабря 2010

Сделайте так:

def mutator(l):
    l.append(10)
    return 10

def f():
    n = 1
    l = [1]
    n = mutator(l)
    print(n,l) # >>> 1, [1,10]

f()

Да, я знаю, что это не умный взлом, который вы хотите; но это работает. : -)

Если вам нужен набор глобальных параметров конфигурации, которые вы можете включить и настроить, прикрепите их все к объекту:

class Settings(object):
    def __init__(self):
         self.n = 1
         self.l = [1]

Теперь вы можете изменить переменные на содержание вашего сердца.

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