How Python Handles 'Argument Passing'

How Python Handles 'Argument Passing'

Are you a programmer experienced in ‘C’ programming language and currently under-way learning ‘Python’ as your new scripting language?

Written by

Preet Singh

Published

7 April 2020

Categories

Data

Acquisition

1. Python from the perspective of a C programmer

If so, you might assume from the code below that the local argument variable z in function f is a copy of integer literal [2], passed in by calling the function call in the global scope.

The script works under that assumption, and it will print out a resulting ‘4’ as shown in the exampled code below:

def f(z):

return z*2

x = 2

y = f(x)

print(y)

#result: 4

2. First-class objects

However, there are no literals in Python. Everything (integers, strings, float, objects, functions and so forth .. ) in Python are objects themselves. These objects are called ‘first class’ objects. Therefore, it is incorrect to state that a copy of literals is passed to the function’s local scope. An example demonstration of said ‘first class’ objects:

1>>>id(2)

270088464

The object [2] is an integer object in the memory with a unique id. The id() function is practically the same as the ‘address of operator’ (&) in the glorious C programming language.

But since Python manages the memory, the address in which the object resides is abstracted to a unique id. Python automatically maps these unique IDs to the actual memory location.

The code below checks whether the type of the object [2] is an integer (i.e. an integer object).

2>>>type(2)

<class ‘int’>

Creating a pointer named [a] pointing to the object [2].

3>>>a=2

Confirming that the object to which pointer [a] points to is of the int class.

4>>>type(a)

<class ‘int’>

The lines below are confirmations that pointer [a] indeed points to the number [2]

5>>>id(2)

270088464

6>>>id(a)

270088464

3. Names, Not Pointers

However, unlike pointers in C, you are unable to perform pointer arithmetic.

In Python, these pointer-like things (which behave like pointers) – are simply called names as Python’s way to reference these partially functional pointers.

Whenever you think you have created a variable in Python – you have made a name and pointed it to a ‘first class’ object.

4. Variable assignment V- naming objects

Given the knowledge that Python is a language with ‘first class’ objects and uses names and things. Others make use of variables, literals, and objects.

Perhaps you’re now thinking about the effect of changing the value of the object.

Now – let me break it down for you around how you would go about this in C:

int x ;

x = 1 ;

x = 2 ;

x = 2 + 1 ;

  1. Line 1 – An int-type variable x is declared, and C initialises the variable by storing an integer literal [0].
  2. Line 2 – The integer literal [1] is stored in [x].
  3. Line 3 – The integer literal [2] is stored in [x], overwriting the existing [1].
  4. Line 4 – The integer literal [3] (yielded from the expression 2+1) is stored in x, overwriting the existing integer literal [2].

Now – prepare for Python:

x = 1

x = 2

x = 2 + 1

  1. Line 1 – Name x points to int object [1].
  2. Line 2 – Name x first cancels its current link to the int object [1] and points to the int object [2].
  3. Line 3 – The expression (2 + 1) is evaluated first by Python to yield a result, which is an int object with numerical value [3]. And name x points to the result int object.

Notice the difference in reassigning/re-pointing behaviour?

The example below highlights the difference between assigning a literal to a variable and pointing a name to an object:

Assigning a literal to a variable:

Create a container and put a new literal into the container. The container can contain various values; hence, the container is referred to as a variable.

Pointing a name to an object:

Point a name to the result of an expression or a function call which returns a new object. For example, the expression 2 + 1 yields the int object [3].

5. Back to the point - passing by copying the name

Now that you’re armed with the key-maker level knowledge of ‘first class’ objects as well as names – let’s re-visit our first example:

def f(z):

return z*2

x = 2

y = f(x)

print(y)

When function f is called on line 4 – the name x in the global scope gets a copy of name z in the function scope and points to the int object [2].

Inside function f – ‘z’ is a standalone name pointing to int object [2]. The return statement returns an integer object [4] to the global scope.

Finally, the global name y is created to point to the int object [4], which the function call returns.

Since the local name [z] is created in the function scope (i.e. on the stack), the name [z] is destroyed as the function returns. Such a way of passing a copy of the name to the local scope of a function is in fact, passing by value. This passing by value happens despite the value being copied to the function's local scope as a reference (aka. name).

A more accurate (although not official – maybe one day) description of this behaviour could be called ‘passing by copying name’.

Thanks to the fact that Python is a ‘first class’ object language – this passing by copying name behaviour is the only way arguments can factually be passed into functions.

The dog and bone.
Subscribe and be the first to hear about news and events.

Written by

Preet Singh
The dog and bone.
Subscribe and be the first to hear about news and events.
View our last posts
Google Universal Analytics arrow to GA4

How to Overcome Universal Analytics’ Sunset & Looming Shutdown

Preet Singh - 5 min read
AI robot tutor helping a student with homework, they are sitting on the couch at home and reading a book

Unlocking the Power of Generative AI: Google’s 10 Free Courses

Tahlia Reynolds - 6 min read

Indago Leads IAB's New Search Working Group

Gary Nissim - 3 min read
Team members thinking together

Get in touch

Ready to get the ball rolling? Drop us a line.

First name*
Last name*
Email address*
Phone number*
Company*
Your message