I am trying to access a local function variable outside the function in Python. So, for example,
bye = ''
def hi():
global bye
something
something
bye = 5
sigh = 10
hi()
print bye
The above works fine as it should. Since I want to find out if I can access bye
outside hi()
without using global bye
, I tried:
def hi():
something
something
bye = 5
sigh = 10
return
hi()
x = hi()
print x.bye
The above gives AttributeError: 'NoneType' object has no attribute 'bye'
.
Then, I tried:
def hi():
something
something
bye = 5
sigh = 10
return bye
hi()
x = hi()
print x.bye
This time it doesn't give even an error.
So, is there a way to access a local function variable (bye
) outside its function (hi()
) without using globals and without printing out variable sigh
as well? (Question was edited to include sigh
after @hcwhsa 's comment below.
This question is related to
python
local-variables
You could do something along these lines (which worked in both Python v2.7.17 and v3.8.1 when I tested it/them):
def hi():
# other code...
hi.bye = 42 # Create function attribute.
sigh = 10
hi()
print(hi.bye) # -> 42
Functions are objects in Python and can have arbitrary attributes assigned to them.
If you're going to be doing this kind of thing often, you could implement something more generic by creating a function decorator that adds a this
argument to each call to the decorated function.
This additional argument will give functions a way to reference themselves without needing to explicitly embed (hardcode) their name into the rest of the definition and is similar to the instance argument that class methods automatically receive as their first argument which is usually named self
— I picked something different to avoid confusion, but like the self
argument, it can be named whatever you wish.
Here's an example of that approach:
def add_this_arg(func):
def wrapped(*args, **kwargs):
return func(wrapped, *args, **kwargs)
return wrapped
@add_this_arg
def hi(this, that):
# other code...
this.bye = 2 * that # Create function attribute.
sigh = 10
hi(21)
print(hi.bye) # -> 42
This doesn't work for class methods. Just use the self
argument already passed being passed to instead of the method name. You can reference class-level attributes through type(self)
. See Function's attributes when in a class.
The problem is you were calling print x.bye after you set x as a string. When you run x = hi()
it runs hi() and sets the value of x to 5 (the value of bye; it does NOT set the value of x as a reference to the bye variable itself). EX: bye = 5; x = bye; bye = 4; print x;
prints 5, not 4
Also, you don't have to run hi() twice, just run x = hi()
, not hi();x=hi()
(the way you had it it was running hi(), not doing anything with the resulting value of 5, and then rerunning the same hi() and saving the value of 5 to the x variable.
So full code should be
def hi():
something
something
bye = 5
return bye
x = hi()
print x
If you wanted to return multiple variables, one option would be to use a list, or dictionary, depending on what you need.
ex:
def hi():
something
xyz = { 'bye': 7, 'foobar': 8}
return xyz
x = hi()
print x['bye']
more on python dictionaries at http://docs.python.org/2/tutorial/datastructures.html#dictionaries
def hi():
bye = 5
return bye
print hi()
I've experienced the same problem. One of the responds to your question led me to the following idea (which worked eventually). I use Python 3.7.
# just an example
def func(): # define a function
func.y = 4 # here y is a local variable, which I want to access; func.y defines
# a method for my example function which will allow me to access
# function's local variable y
x = func.y + 8 # this is the main task for the function: what it should do
return x
func() # now I'm calling the function
a = func.y # I put it's local variable into my new variable
print(a) # and print my new variable
Then I launch this program in Windows PowerShell and get the answer 4. Conclusion: to be able to access a local function's variable one might add the name of the function and a dot before the name of the local variable (and then, of course, use this construction for calling the variable both in the function's body and outside of it). I hope this will help.
You could do something along this lines:
def static_example():
if not hasattr(static_example, "static_var"):
static_example.static_var = 0
static_example.static_var += 1
return static_example.static_var
print static_example()
print static_example()
print static_example()
Source: Stackoverflow.com