0

If I had the code:

num = 3

def add(variable, number):
  variable += number

add(num, 2)
print(num)

It would output 3 because inside the function, the temporary variable variable inside the function is being added to instead of the num variable. Is there a way to make it so when I pass num as the first argument, 3 would be added to num instead of variable and num would be changed to 5?

  • Using `global` (or `nonlocal`) would kind of work, but you'd have to know and explicitly use the name of the outside variable. Otherwise, the closest thing you could do would be to use a mutable type, rather than an integer. – CrazyChucky Jul 22 '22 at 20:48
  • One (hacky) way you can do this is to wrap the argument in a mutable type like `list`. Changes to mutable objects will "leak" outside of functions. – 0x5453 Jul 22 '22 at 20:50
  • 2
    Variable, no. *Value*, yes, if it is mutable. – chepner Jul 22 '22 at 20:59
  • [This blog article](https://nedbatchelder.com/text/names.html) explains in detail how this works. It might seem overwhelming at first, but this is a critical concept to understand in order to master python. – Code-Apprentice Jul 22 '22 at 21:00

5 Answers5

3

When you call a function with arguments, you pass the arguments value to the function. That function has no connection to the original variable and it cannot be reassigned to a new value.

The correct way to accomplish your goal here is to return a new value:

num = 3

def add(variable, number):
  return variable + number

num = add(num, 2)
print(num)
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • You *can* change arguments if they are a mutable type like `list`. – 0x5453 Jul 22 '22 at 20:52
  • See https://stackoverflow.com/questions/15148496/passing-an-integer-by-reference-in-python for an example to wrap it in a list. It goes without saying that the strongly recommended way is to return the value. – Jens Jul 22 '22 at 20:53
  • 2
    @0x5453 You bring up a good point. My wording "change the value of the variable" is ambiguous. You can mutate the value of an argument, yes, but you can't reassign the argument variable to a new value. – Code-Apprentice Jul 22 '22 at 20:54
  • 1
    @0x5453 I edited my wording to try to be more precise. – Code-Apprentice Jul 22 '22 at 20:58
1

You could write it like this:

num = 3


def add(n1, n2):
    return n1 + n2


print(add(num, 2))

The original assignment is not going to update when printing num.

andrew
  • 81
  • 1
  • 8
1

I think you need to explicitly assign the new value to the num variable. For example, you could do:

num = 3

def add(variable, number)
    return variable + number

num = add(num, 2)
print(num) #Prints out 5
1

Your question touches on one of the more esotheric and easy to misunderstand features of Python: mutables and immutables.

Here is the official documentation on mutable and immutable sequence types;

https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types https://docs.python.org/3/library/stdtypes.html#immutable-sequence-types

As you can tell, only sequences and complex objects are mutable, and thus may be altered by the function.

Base types like integers and floats cannot be changes within the function as you describe, though strings can, as they count as sequences.

In your example, you're using an integer - so this will not work. However, with a string, array, dictionary or complex object (a class of your own design), this _will work.

If you're coming at it from another programming language like C++, think of mutables like references, and immutables like values. If you pass a value, any changes to the object referenced within the scope of the function do not live past the life of the function scope. Any changes to objects with references on them, however, do persist.

This post does an excellent job of explaining this in much more depth, and I would highly recommend skimming it;

https://medium.com/@meghamohan/mutable-and-immutable-side-of-python-c2145cf72747

MaVCArt
  • 745
  • 8
  • 21
0

The purpose of the add function is to add two numbers together which will result in a number. This is something completely different than doing operations on already existing variables. If you want to use variables both inside and outside function, you can use the keyword 'global'. This lets the function know that this is a globally defined variable and you will be able to do operations on it. So you can for example do:

num = 3

def add(number):
    global num
    num += number

add(2)
print(num)

Which will print 5

If you just want a function to add two numbers and assign this result to the already globally defined variable, you can use:

num = 3

def add(variable, number):
  return variable + number

num = add(num, 2)
print(num)

This will also print 5