如何修改另一个范围的变量?

时间:2010-12-14 21:38:03

标签: python scope

Currectly,我正在尝试以下方法:一些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()&共
  • 使用堆叠帧播放& 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 个答案:

答案 0 :(得分:3)

class AttributeCollection(object):
    pass
shared_settings= AttributeCollection()
# now improvise
shared_settings.temperature= 30
shared_settings.samples= []
# etc

传递shared_settings,或将其设为全局,并将其属性设置为您想要的任何内容。

你知道,函数的locals()只是一个命名空间(并针对它进行了优化),可以在该函数内部进行操作(并且该函数正在运行)。使用另一个命名空间(在我的建议中,shared_settings对象)作为代码的常用操场。

答案 1 :(得分:0)

这样做:

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]

现在您可以将变量更改为您的心灵内容。