Accessing the outer scope in Python 2.6
Solution 1
Define the variables outside of the functions and use the global
keyword.
s, n = "", 0
def outer():
global n, s
n = 123
s = 'qwerty'
modify()
def modify():
global n, s
s = 'abcd'
n = 456
Solution 2
Sometimes I run across code like this. A nested function modifies a mutable object instead of assigning to a nonlocal
:
def outer():
s = [4]
def inner():
s[0] = 5
inner()
Solution 3
Your options are to use 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 those 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
Solution 4
You can probably also do this (not saying it is right);
define a function that returns an array with rows like so
["a = qwerty","n = 123"]
Then do in the scope you need the vars
for row in array:
eval(row)
this is pretty darn hacky though.
kolypto
Enthusiastic Python/JS back-end developer. Loves exceptional projects and challenging tasks. Architects chaos into well-structured formations. Friendly and business-minded. Loves people. Always smiles :) CV and Contacts
Updated on July 29, 2022Comments
-
kolypto almost 2 years
Say, I have some scope with variables, and a function called in this scope wants to change some immutable variables:
def outer(): s = 'qwerty' n = 123 modify() def modify(): s = 'abcd' n = 456
Is it possible somehow to access the outer scope? Something like
nonlocal
variables from Py3k.Sure I can do
s,n = modify(s,n)
in this case, but what if I need some generic 'injection' which executes there and must be able to reassign to arbitrary variables?I have performance in mind, so, if possible,
eval
& stack frame inspection is not welcome :)
UPD: It's impossible. Period. However, there are some options how to access variables in the outer scope:
- Use globals. By the way,
func.__globals__
is a mutable dictionary ;) - Store variables in a dict/class-instance/any other mutable container
- Give variables as arguments & get them back as a tuple:
a,b,c = innerfunc(a,b,c)
- Inject other function's bytecode. This is possible with
byteplay
python module.
- Use globals. By the way,
-
Admin over 13 yearsReplace
and
withxor
for this to work. Rewrite from scratch for good advice. -
gotgenes over 13 yearsHe means "define them outside, or use
global
, but not both". -
Admin over 13 yearsIf you defined the variables in global scope and declared them
global
(as opposed to doing either), then it would, strictly speaking, work - but of course that's not a proper solution. (Edit: Just noticed I mixed things up... should be "replacexor
withand
" - iFail) -
gotgenes over 13 yearsThat's interesting. Ugly, but interesting.
-
joeforker over 13 yearsYou can type outer.s = 4, but that will assign an attribute to the outer() function. It is not the same as assigning to the local variable called s.
-
Ord over 11 yearsI think you mean
exec(row)
; eval is for expressions only -
kolypto almost 4 yearsThe question is about Python 2.6 ;)