[Tutor] Accessing callers context from callee method

wesley chun wescpy at gmail.com
Tue Feb 24 20:59:03 CET 2009


> when i call a method foo from another method func. can i access func context
> variables or locals() from foo
> so
> def func():
>   i=10
>   foo()
>
> in foo, can i access func's local variables


A. python has statically-nested scoping, so you can do it as long as you:

1. define foo() as an inner function -- its def is contained within
func()'s def:
def func():
    i = 10
    def foo():
        print i

2. you don't define a variable with the same name locally. in other
words, you do have access to func()'s 'i' as long as you don't create
another 'i' within foo() -- if you do, only your new local 'i' will be
within your scope.

B. another alterative is to pass in all of func()'s local variables to foo():

foo(**locals())

this will require you to accept the incoming dictionary in foo() and
access the variables from it instead of having them be in foo()'s
scope.

C. in a related note, your question is similar to that of global vs.
local variables. inside a function, you have access to the global as
long as you don't define a local using the same name. should you only
wish to manipulate the global one, i.e. assign a new value to it
instead of creating a new local variable with that name, you would
need to use the "global" keyword to specify that you only desire to
use and update the global one.

i = 0
def func():
    i = 10

in this example, the local 'i' in func() hides access to the global
'i'. in the next code snippet, you state you only want to
access/update the global 'i'... IOW, don't create a local one:

i = 0
def func():
    global i
    i = 10

D. this doesn't work well for inner functions yet:

i = 0
def func():
    i = 10
    def foo():
        i = 20

the 'i' in foo() shadows/hides access to func()'s 'i' as well as the
global 'i'. if you issue the 'global' keyword, that only gives you
access to the global one:

i = 0
def func():
    i = 10
    def foo():
        global i
        i = 20

you cannot get access to func()'s 'i' in this case.

E. however, starting in Python 3.x, you'll be able to do somewhat
better with the new 'nonlocal' keyword:

i = 0
print('globally, i ==', i)
def func():
    i = 10
    print('in func(), i ==', i)
    def foo():
        nonlocal i
        i = 20
        print('in foo(), i ==', i)
    foo()
    print('in func() after calling foo(), i ==', i)
func()

in this case, foo() modified func()'s 'i'.

hope this helps!
-- wesley
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2007,2001
"Python Fundamentals", Prentice Hall, (c)2009
    http://corepython.com

wesley.j.chun :: wescpy-at-gmail.com
python training and technical consulting
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com


More information about the Tutor mailing list