问题
Currectly, I'm trying the following: Some mutator function accepts other function's local scope using 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)
and that works as expected: I was able to modify mutable list contents but failed to 'rebind' another immutable int to the same name.
Currently, I see some options:
eval(),exec()& Co- Play with stack frames & local variables in
mutator() - Keep such variables in a
dict: not very handy but probably the best one
The restriction is: target function f() can contain just one function call, possibly with arguments, and that function should be able to alter values in f()s current scope.
So.. is there a way to reintroduce variable's value (bind another object) at runtime? I don't believe there is no good trick to achive this!
Here's an example of the thing I'm trying to achieve:
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']
I don't want to use data dict here: ability to modify them as local variables would be much better & pretty. Note that q QuerySet object is mutable & mutators can alter its contents.
回答1:
class AttributeCollection(object):
pass
shared_settings= AttributeCollection()
# now improvise
shared_settings.temperature= 30
shared_settings.samples= []
# etc
Pass that shared_settings around, or make it global, and set its attributes to whatever you desire.
You see, the locals() of a function are just a namespace meant (and optimised for it) to be manipulated inside that function (and while that function is running). Use another namespace (in my suggestion, the shared_settings object) as a common playground for your code.
回答2:
Do it this way:
def mutator(l):
l.append(10)
return 10
def f():
n = 1
l = [1]
n = mutator(l)
print(n,l) # >>> 1, [1,10]
f()
Yeah, I know it isn't the clever hack you want; but it works. :-)
If you want a set of global configuration options that you can turn on and tune, stick all of them on an object:
class Settings(object):
def __init__(self):
self.n = 1
self.l = [1]
Now you can change the variables to your hearts content.
来源:https://stackoverflow.com/questions/4444498/how-to-modify-variables-of-another-scope