Access to the outside area in Python 2.6

Let's say I have a scope with variables, and a function called in that scope wants to change some immutable variables:

  def outer ():
     s = 'qwerty'
     n = 123
     modify ()

 def modify ():
     s = 'abcd'
     n = 456

Is it possible to somehow access the external area? Something like nonlocal variables from Py3k.

Of course, I can do s,n = modify(s,n) in this case, but what if I need some kind of general β€œinjection” that runs there, and should be able to reassign to arbitrary variables?

I have performance, so if possible, eval and checking the stack frame is not welcome :)


UPD : This is not possible. Period. However, there are several ways to access variables in the external area:

  • Use global variables. By the way, func.__globals__ is a mutable dictionary;)
  • Store variables in dict / class-instance / any other mutable container
  • Give the variables as arguments and return them as a tuple: a,b,c = innerfunc(a,b,c)
  • Enter another function bytecode. This is possible with the python byteplay module.
+7
source share
5 answers

This is not how nonlocal works. It does not provide dynamic scaling (it is just a huge PITA, awaiting appearance and even rarer than your average "evil" function). It simply captures lexical reach.

In any case, you cannot do what you mean (and I would say that this is good). There is not even a dirty, but easy hack (and while we are on it: such hacks are not discouraged, because they are usually a little worse!). Just forget about it and correctly solve the real problem (you will not name it, so we can not say anything about it).

The closest you can get is to define some kind of object that carries everything you want to share and pass it explicitly (e.g. create a class and use self , as suggested in another answer). But it is relatively cumbersome to do everywhere, and still hacking (although better than dynamic scaling, because "explicit is better than implicit").

+3
source

Define variables outside functions and use the global .

 s, n = "", 0 def outer(): global n, s n = 123 s = 'qwerty' modify() def modify(): global n, s s = 'abcd' n = 456 
+7
source

Sometimes I run code like this. The nested function modifies the changed object instead of nonlocal :

 def outer(): s = [4] def inner(): s[0] = 5 inner() 
+7
source

Your options are for using global variables,

 s = None n = None def outer(self): global s global n s = 'qwerty' n = 123 modify() def modify(self): global s global n s = 'abcd' n = 456 

or define them as methods and use a class or instance variable.

 class Foo(object): def __init__(self): self.s = None self.n = None def outer(self): self.s = 'qwerty' self.n = 123 self.modify() def modify(self): self.s = 'abcd' self.n = 456 
+3
source

Perhaps you can also do this (not assuming that this is correct);

define a function that returns an array with such strings

 ["a = qwerty","n = 123"] 

Then follow in the area where you need vars

 for row in array: eval(row) 

it's pretty damn hacks though.

+1
source

All Articles