You can use the return statement to return a value from a function, this does not make it so that the returned variable (value) becomes available in the scope of the caller. To use the value in the caller you can either use it directly in a statement or capture the value in a variable.

Here's some code to demonstrate this:

def foo():
    x = 'hello world'
    return x  # return 'hello world' would do, too

foo()
print(x)   # NameError - x is not defined outside the function

y = foo()
print(y)   # this works

x = foo()
print(x)   # this also works, and it's a completely different x than that inside
           # foo()

z = bar(x) # of course, now you can use x as you want

z = bar(foo()) # but you don't have to
Answer from Tim Pietzcker on Stack Overflow
Top answer
1 of 4
47

You can use the return statement to return a value from a function, this does not make it so that the returned variable (value) becomes available in the scope of the caller. To use the value in the caller you can either use it directly in a statement or capture the value in a variable.

Here's some code to demonstrate this:

def foo():
    x = 'hello world'
    return x  # return 'hello world' would do, too

foo()
print(x)   # NameError - x is not defined outside the function

y = foo()
print(y)   # this works

x = foo()
print(x)   # this also works, and it's a completely different x than that inside
           # foo()

z = bar(x) # of course, now you can use x as you want

z = bar(foo()) # but you don't have to
2 of 4
10

Effectively, there are two ways: directly and indirectly.

The direct way is to return a value from the function, as you tried, and let the calling code use that value. This is normally what you want. The natural, simple, direct, explicit way to get information back from a function is to return it. Broadly speaking, the purpose of a function is to compute a value, and return signifies "this is the value we computed; we are done here".

Directly using return

The main trick here is that return returns a value, not a variable. So return x does not enable the calling code to use x after calling the function, and does not modify any existing value that x had in the context of the call. (That's presumably why you got a NameError.)

After we use return in the function:

def example():
    x = 'hello world'
    return x

we need to write the calling code to use the return value:

result = example()
print(result)

The other key point here is that a call to a function is an expression, so we can use it the same way that we use, say, the result of an addition. Just as we may say result = 'hello ' + 'world', we may say result = foo(). After that, result is our own, local name for that string, and we can do whatever we want with it.

We can use the same name, x, if we want. Or we can use a different name. The calling code doesn't have to know anything about how the function is written, or what names it uses for things.1

We can use the value directly to call another function: for example, print(foo()).2 We can return the value directly: simply return 'hello world', without assigning to x. (Again: we are returning a value, not a variable.)

The function can only return once each time it is called. return terminates the function - again, we just determined the result of the calculation, so there is no reason to calculate any further. If we want to return multiple pieces of information, therefore, we will need to come up with a single object (in Python, "value" and "object" are effectively synonyms; this doesn't work out so well for some other languages.)

We can make a tuple right on the return line; or we can use a dictionary, a namedtuple (Python 2.6+), a types.simpleNamespace (Python 3.3+), a dataclass (Python 3.7+), or some other class (perhaps even one we write ourselves) to associate names with the values that are being returned; or we can accumulate values from a loop in a list; etc. etc. The possibilities are endless..

On the other hand, the function returns whether you like it or not (unless an exception is raised). If it reaches the end, it will implicitly return the special value None. You may or may not want to do it explicitly instead.


Indirect methods

Other than returning the result back to the caller directly, we can communicate it by modifying some existing object that the caller knows about. There are many ways to do that, but they're all variations on that same theme.

If you want the code to communicate information back this way, please just let it return None - don't also use the return value for something meaningful. That's how the built-in functionality works.

In order to modify that object, the called function also has to know about it, of course. That means, having a name for the object that can be looked up in a current scope. So, let's go through those in order:

Local scope: Modifying a passed-in argument

If one of our parameters is mutable, we can just mutate it, and rely on the caller to examine the change. This is usually not a great idea, because it can be hard to reason about the code. It looks like:

def called(mutable):
    mutable.append('world')

def caller():
    my_value = ['hello'] # a list with just that string
    called(my_value)
    # now it contains both strings

If the value is an instance of our own class, we could also assign to an attribute:

class Test:
    def __init__(self, value):
        self.value = value

def called(mutable):
    mutable.value = 'world'

def caller():
    test = Test('hello')
    called(test)
    # now test.value has changed

Assigning to an attribute does not work for built-in types, including object; and it might not work for some classes that explicitly prevent you from doing it.

Local scope: Modifying self, in a method

We already have an example of this above: setting self.value in the Test.__init__ code. This is a special case of modifying a passed-in argument; but it's part of how classes work in Python, and something we're expected to do. Normally, when we do this, the calling won't actually check for changes to self - it will just use the modified object in the next step of the logic. That's what makes it appropriate to write code this way: we're still presenting an interface, so the caller doesn't have to worry about the details.

class Example:
    def __init__(self):
        self._words = ['hello']
    def add_word(self):
        self._words.append('world')
    def display(self):
        print(*self.words)

x = Example()
x.add_word()
x.display()

In the example, calling add_word gave information back to the top-level code - but instead of looking for it, we just go ahead and call display.3

See also: Passing variables between methods in Python?

Enclosing scope

This is a rare special case when using nested functions. There isn't a lot to say here - it works the same way as with the global scope, just using the nonlocal keyword rather than global.4

Global scope: Modifying a global

Generally speaking, it is a bad idea to change anything in the global scope after setting it up in the first place. It makes code harder to reason about, because anything that uses that global (aside from whatever was responsible for the change) now has a "hidden" source of input.

If you still want to do it, the syntax is straightforward:

words = ['hello']
def add_global_word():
    words.append('world')

add_global_word() # `words` is changed

Global scope: Assigning to a new or existing global

This is actually a special case of modifying a global. I don't mean that assignment is a kind of modification (it isn't). I mean that when you assign a global name, Python automatically updates a dict that represents the global namespace. You can get that dict with globals(), and you can modify that dict and it will actually impact what global variables exist. (I.e., the return from globals() is the dictionary itself, not a copy.)5

But please don't. That's even worse of an idea than the previous one. If you really need to get the result from your function by assigning to a global variable, use the global keyword to tell Python that the name should be looked up in the global scope:

words = ['hello']

def replace_global_words():
    global words
    words = ['hello', 'world']

replace_global_words() # `words` is a new list with both words

Global scope: Assigning to or modifying an attribute of the function itself

This is a rare special case, but now that you've seen the other examples, the theory should be clear. In Python, functions are mutable (i.e. you can set attributes on them); and if we define a function at top level, it's in the global namespace. So this is really just modifying a global:

def set_own_words():
    set_own_words.words = ['hello', 'world']

set_own_words()
print(*set_own_words.words)

We shouldn't really use this to send information to the caller. It has all the usual problems with globals, and it's even harder to understand. But it can be useful to set a function's attributes from within the function, in order for the function to remember something in between calls. (It's similar to how methods remember things in between calls by modifying self.) The functools standard library does this, for example in the cache implementation.

Builtin scope

This doesn't work. The builtin namespace doesn't contain any mutable objects, and you can't assign new builtin names (they'll go into the global namespace instead).


Some approaches that don't work in Python

Just calculating something before the function ends

In some other programming languages, there is some kind of hidden variable that automatically picks up the result of the last calculation, every time something is calculated; and if you reach the end of a function without returning anything, it gets returned. That doesn't work in Python. If you reach the end without returning anything, your function returns None.

Assigning to the function's name

In some other programming languages, you are allowed (or expected) to assign to a variable with the same name as the function; and at the end of the function, that value is returned. That still doesn't work in Python. If you reach the end without returning anything, your function still returns None.

def broken():
    broken = 1

broken()
print(broken + 1) # causes a `TypeError`

It might seem like you can at least use the value that way, if you use the global keyword:

def subtly_broken():
    global subtly_broken
    subtly_broken = 1

subtly_broken()
print(subtly_broken + 1) # 2

But this, of course, is just a special case of assigning to a global. And there's a big problem with it - the same name can't refer to two things at once. By doing this, the function replaced its own name. So it will fail next time:

def subtly_broken():
    global subtly_broken
    subtly_broken = 1

subtly_broken()
subtly_broken() # causes a `TypeError`

Assigning to a parameter

Sometimes people expect to be able to assign to one of the function's parameters, and have it affect a variable that was used for the corresponding argument. However, this does not work:

def broken(words):
    words = ['hello', 'world']

data = ['hello']
broken(data) # `data` does not change

Just like how Python returns values, not variables, it also passes values, not variables. words is a local name; by definition the calling code doesn't know anything about that namespace.

One of the working methods that we saw is to modify the passed-in list. That works because if the list itself changes, then it changes - it doesn't matter what name is used for it, or what part of the code uses that name. However, assigning a new list to words does not cause the existing list to change. It just makes words start being a name for a different list.

For more information, see How do I pass a variable by reference?.


1 At least, not for getting the value back. If you want to use keyword arguments, you need to know what the keyword names are. But generally, the point of functions is that they're an abstraction; you only need to know about their interface, and you don't need to think about what they're doing internally.

2 In 2.x, print is a statement rather than a function, so this doesn't make an example of calling another function directly. However, print foo() still works with 2.x's print statement, and so does print(foo()) (in this case, the extra parentheses are just ordinary grouping parentheses). Aside from that, 2.7 (the last 2.x version) has been unsupported since the beginning of 2020 - which was nearly a 5 year extension of the normal schedule. But then, this question was originally asked in 2010.

3Again: if the purpose of a method is to update the object, don't also return a value. Some people like to return self so that you can "chain" method calls; but in Python this is considered poor style. If you want that kind of "fluent" interface, then instead of writing methods that update self, write methods that create a new, modified instance of the class.

4 Except, of course, that if we're modifying a value rather than assigning, we don't need either keyword.

5 There's also a locals() that gives you a dict of local variables. However, this cannot be used to make new local variables - the behaviour is undefined in 2.x, and in 3.x the dict is created on the fly and assigning to it has no effect. Some of Python's optimizations depend on the local variables for a function being known ahead of time.

🌐
Real Python
realpython.com › python-return-statement
The Python return Statement: Usage and Best Practices – Real Python
June 14, 2024 - In Python, the return statement allows you to send values back to the caller from a function. To return a single value, use the return keyword followed by the value. This can be any data type, such as a number, string, list, or object.
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Learn_web_development › Core › Scripting › Return_values
Function return values - Learn web development | MDN
You want to get to a final result, ... this variable in the next stage of the calculation. To return a value from a custom function, you need to use the return keyword....
🌐
Revenera
docs.revenera.com › installshield24helplib › helplibrary › LangrefReturning_a_value_from_a_functio.htm
Returning Values from Functions
Like InstallScript’s built-in functions, user-defined functions can be designed to return a value to the caller. To return a value from a function, you must include a return statement, followed by the value to be returned, before the function’s end statement.
🌐
Runestone Academy
runestone.academy › ns › books › published › foppff › functions_returning-a-value-from-a-function.html
Returning a value from a function
Notice something important here: the name of the variable we pass as an argument does not have to have anything to do with the name of the formal parameter — an_integer. You can see this very clearly in the Codelens: it doesn’t matter what names the caller uses — the_integer or another_integer). When square is executed, inside that function, its parameter, a local variable — an_integer, is given the value that is passed, the local temporary variable — result is determined, and finally, is the return value that the function produces.
🌐
Learn C++
learncpp.com › cpp-tutorial › function-return-values-value-returning-functions
2.2 — Function return values (value-returning functions) – Learn C++
When the program goes to initialize num, it will see that there is a function call to getValueFromUser(), so it will go execute that function. Function getValueFromUser, asks the user to enter a value, and then it returns that value back to the caller (main()). This return value is used as ...
🌐
Runestone Academy
runestone.academy › ns › books › published › fopp › Functions › Returningavaluefromafunction.html
12.5. Returning a value from a function — Foundations of Python Programming
The return statement is followed by an expression which is evaluated. Its result is returned to the caller as the “fruit” of calling this function. Because the return statement can contain any Python expression we could have avoided creating the temporary variable y and simply used return x*x.
Find elsewhere
🌐
Freedom Scientific
support.freedomscientific.com › Content › Documents › Other › ScriptManual › 12-4_FunctionsThatReturnValues.htm
12.4 Functions that Return Values
An example of storing a string value returned by a function called MyFunction in a local variable follows: Script MyScript () Var String sText Let sText = MyFunction (); store the return value of MyFunction in sText If sText != "" Then; the function actually returned a value other than null or nothing SayFormattedMessage (OT_MESSAGE, sText) EndIf EndScript · You can also use the return value of one function as the parameter for another. Using the previous example, the return value from MyFunction could be passed directly to the SayFormattedMessage function without storing it in a local variable first.
🌐
Reddit
reddit.com › r/learnpython › when/how to declare return variable
r/learnpython on Reddit: when/how to declare return variable
December 9, 2022 -

My understanding is that you need to declare whatever variable you want to return outside of the function, since otherwise you would have a locality (I think that's the word?) issue.

It just seems a bit ugly to declare at the top of my program every return variable. Declaring it as global within the function visually looks best to me. Is this an "acceptable" use of global?

What is the best practice for this? Thanks.

🌐
Quora
quora.com › How-do-I-return-a-variable-in-Python
How to return a variable in Python - Quora
Answer (1 of 5): So, you don’t really. You return a value. You may return the value of a variable. Consider: [code]return x [/code]and [code]return 3**.5 [/code]In either case, I’m returning a value. In this first case, it’s whatever the value of x is. In the second case, it’s the value ...
Top answer
1 of 3
21

Functions shouldn't have to know what scope they're called from; the point of a function is to make a re-usable block of code that can be invoked multiple times from different places.

You communicate information to a function by passing it through its input variables. The function communicates information back to its caller by returning it.

Managing the variables of a scope is the job of the code in that scope not any functions it invokes. If you need to set variables to values determined by a function, then you have the function return those values and you use them to set the variables. If the values the function is calculating depend on the values of variables you have in the calling scope, then you need to pass them to the function as arguments. The function you're calling shouldn't have to know what variables you're using, and shouldn't be able to mess with them.

Putting that all together, what you want to do is something like this:

def find_chamber_discard(chambersinreactor, cardsdiscarded):
    chambersinreactor += 1
    cardsdiscarded += 1
    return (chambersinreactor, cardsdiscarded)

chambersinreactor = 0;
cardsdiscarded = 0;

chambersinreactor, cardsdiscarded = find_chamber_discard(chambersinreactor, cardsdiscarded)

print chambersinreactor
print cardsdiscarded

There are ways to get around this with global variables or manipulating mutable data structures, but ultimately they make your program less flexible and more likely to contain errors that will be difficult to spot. There is a place for those techniques, but the first method you reach for to communicate information to and from functions really should be passing arguments and receiving return values.

2 of 3
2

One approach is to use mutable values, like dicts or lists:

settings = dict(
    chambersinreactor = 0,
    cardsdiscarded = 0
)

def find_chamber_discard():
    settings['chambersinreactor'] += 1
    settings['cardsdiscarded'] += 1

find_chamber_discard()

print settings['chambersinreactor']
print settings['cardsdiscarded']

However, if you have a function that is changing some state, you're probably better off wrapping that all up in class, as that's what they're for:

class CardCounter(object):
    def __init__(self):
        chambersinreactor = 0
        cardsdiscarded = 0

    def find_chamber_discard(self, hand):
        for card in hand:
            if card.is_chamber:
                self.chambersinreactor += 1
            if card.is_discarded:
                self.cardsdiscarded += 1

If what you're doing is counting, maybe you could use Counter:

from collections import Counter

def test_for_chamberness(x): return x == 'C'
def test_for_discarded(x): return x == 'D'

def chamber_or_discard(card):
    if test_for_chamberness(card):
        return 'chambersinreactor'
    if test_for_discarded(card):
        return 'cardsdiscarded'

hand = ['C','C','D','X','D','E','C']

print Counter(
    x for x in (chamber_or_discard(card) for card in hand) if x is not None
)

Personally, I'd go for the class approach, perhaps even wrapping Counter, as it keeps all the associated functionality together.

🌐
PHP
php.net › manual › en › functions.returning-values.php
PHP: Returning values - Manual
', ' . $obj2->x . "\n"; # (2) Scalars are not passed by reference or returned as such function scalar_inc_x($x) { $x++; return $x; } $x = 1; $x2 = scalar_inc_x($x); scalar_inc_x($x2); print $x . ', ' . $x2 . "\n"; # (3) You have to force pass by reference and return by reference on scalars function &scalar_ref_inc_x(&$x) { $x++; return $x; } $x = 1; $x2 =& scalar_ref_inc_x($x); # Need reference here as well as the function sig scalar_ref_inc_x($x2); print $x .
🌐
Steve's Data Tips and Tricks
spsanderson.com › steveondata › posts › 2025-04-21
How to Return Value from a Function in R: A Complete Guide – Steve’s Data Tips and Tricks
Learn how to return values from functions in R with practical examples. Explore implicit returns, the return() function, and techniques for returning multiple values in simple, easy-to-follow code. Perfect for R programmers of all levels.
🌐
Python Tips
book.pythontips.com › en › latest › global_&_return.html
8. Global & Return — Python Tips 0.1 documentation
So what if you want to return two variables from a function instead of one? There are a couple of approaches which new programmers take. The most famous approach is to use global keyword.
🌐
W3Schools
w3schools.com › js › js_functions.asp
JavaScript Function Study Path
The return statement is used to return a value from a function · Step 5Intermediate · Function parameters and arguments are distinct concepts · Parameters are the names listed in the function definition · Arguments are the values received ...
🌐
Datamentor
datamentor.io › r-programming › return-function
R Return Value from Function (With Examples)
We generally use explicit return() functions to return a value immediately from a function.
🌐
Team Treehouse
teamtreehouse.com › community › how-to-call-a-function-and-how-to-return-value-to-a-variable-called
How to call a function and how to return value to a variable called. (Example) | Treehouse Community
August 18, 2023 - To pass task 1, your hello_student function needs to: return the string "Hello" followed by the value of the name parameter. When you click "Check work", the Treehouse Checker will run code like this: ... Let's get back to your code.