Open In Colab

Basic Python Semantics: Variables & Objects

This section will begin to cover the basic semantics of the Python language. As opposed to the syntax covered in the previous section, the semantics of a language involve the meaning of the statements. As with our discussion of syntax, here we'll preview a few of the essential semantic constructions in Python to give you a better frame of reference for understanding the code in the following sections.

This section will cover the semantics of variables and objects, which are the main ways you store, reference, and operate on data within a Python script.

Variables

A variable is a named location used to store data in the memory. For now, it is helpful to think of variables as a container that holds data which can be changed later throughout programming. For example,

number = 10

Here, we have created a named number. We have assigned value 10 to the variable.

You can think variable as a bag to store books in it and those books can be replaced at any time.

Let's consider the following example:

In [ ]:
number = 10
print(number)

number = 1.1
print(number)
10
1.1

Initially, the value of number was 10. Later it's changed to 1.1.

Note: In Python, we don't assign values to the variables, whereas Python gives the reference of the object (value) to the variable.

Assigning a value to a Variable in Python

As you can see from the above example, you can use the assignment operator = to assign a value to a variable.

Example 1: Declaring and assigning a value to a variable

In [ ]:
website = "apple.com"
print(website)
apple.com

In the above program, we assigned a value apple.com to the variable website. Then we print the value assigned to website i.e. apple.com

Example 2: Changing the value of a variable

In [ ]:
website = "apple.com"
print(website)

# assigning a new variable to website
website = "easypass-learning.ch"

print(website)
apple.com
programiz.com

In the above program, we have assigned apple.com to the website variable initially. Then, it's value is changed to easypass-learning.ch.

Example 3: Assigning multiple values to multiple variables

In [ ]:
a, b, c = 5, 3.2, "Hello"

print (a)
print (b)
print (c)
5
3.2
Hello

If we want to assign the same value to multiple variables at once, we can do this as

In [ ]:
x = y = z = "same"

print (x)
print (y)
print (z)
same
same
same

The second program assigns the same string to all the three variables x, y and z.

Python Variables Are Pointers

As we have seen, assigning variables in Python is as easy as putting a variable name to the left of the equals (=) sign:

# assign 4 to the variable x
x = 4

This may seem straightforward, but if you have the wrong mental model of what this operation does, the way Python works may seem confusing. We'll briefly dig into that here.

Above we stated that variables are best thought of as containers or buckets into which you put data. While this holds true for other programming languages, it is a bit more complicated when it comes to Python. Let us elaborate.

In other programming languages such as C, for example, when you write

// C code
int x = 4;

you are essentially defining a "memory bucket" named x, and putting the value 4 into it. In Python, by contrast, variables are best thought of not as containers but as pointers. So in Python, when you write

x = 4

you are essentially defining a pointer named x that points to some other bucket containing the value 4. Note one consequence of this: because Python variables just point to various objects, there is no need to "declare" the variable, or even require the variable to always point to information of the same type! This is the sense in which people say Python is dynamically-typed: variable names can point to objects of any type. So in Python, you can do things like this:

In [ ]:
x = 1         # x is an integer
x = 'hello'   # now x is a string
x = [1, 2, 3] # now x is a list

This dynamic typing is one of the pieces that makes Python so quick to write and easy to read.

There is a consequence of this "variable as pointer" approach that you need to be aware of. If we have two variable names pointing to the same mutable object, then changing one will change the other as well! For example, let's create and modify a list:

In [ ]:
x = [1,2]
y = x

We've created two variables x and y which both point to the same object. Because of this, if we modify x, we'll see that y will be modified as well:

In [ ]:
print(y)
[1, 2]
In [ ]:
x.append(3) # append 3 to the list pointed to by x
print(y) # y's list is modified as well!
[1, 2, 3]

This behavior might seem confusing if you're wrongly thinking of variables as buckets that contain data. But if you're correctly thinking of variables as pointers to objects, then this behavior makes sense.

Note also that if we use "=" to assign another value to x, this will not affect the value of y – assignment is simply a change of what object the variable points to:

In [ ]:
x = 'something else'
print(y)  # y is unchanged
[1, 2, 3]

Again, this makes perfect sense if you think of x and y as pointers, and the "=" operator as an operation that changes what the name points to.

You might wonder whether this pointer idea makes arithmetic operations in Python difficult to track, but Python is set up so that this is not an issue. Numbers, strings, and other simple types are immutable: you can't change their value – you can only change what values the variables point to. So, for example, it's perfectly safe to do operations like the following:

In [ ]:
x = 10
y = x
x += 5  # add 5 to x's value, and assign it to x
print("x =", x)
print("y =", y)
x = 15
y = 10

When we call x += 5, we are not modifying the value of the 10 object pointed to by x; we are rather changing the variable x so that it points to a new integer object with value 15. For this reason, the value of y is not affected by the operation.

Everything Is an Object

Python is an object-oriented programming language, and in Python everything is an object.

Let's flesh-out what this means. Earlier we saw that variables are simply pointers, and the variable names themselves have no attached type information. This leads some to claim erroneously that Python is a type-free language. But this is not the case! Consider the following:

In [ ]:
# use the function type(x) to find out what data type (integer, string, floating number, etc.) the variable x contains

x = 4
type(x) # 4 is an integer
Out[ ]:
int
In [ ]:
x = 'hello'
type(x) # hello is a string
Out[ ]:
str
In [ ]:
x = 3.14159
type(x) # pi is a floating number
Out[ ]:
float

Python has certain data types (e.g. integer, floating number, strings, lists, etc.); however, the types are linked not to the variable names but to the objects themselves.

In object-oriented programming languages like Python, an object is an entity that contains data along with associated metadata and/or functionality. In Python everything is an object, which means every entity has some metadata (called attributes) and associated functionality (called methods). These attributes and methods are accessed via the dot syntax.

For example, before we saw that lists have an append method, which adds an item to the list, and is accessed via the dot (".") syntax:

In [ ]:
L = [1, 2, 3]
L.append(100)
print(L)
[1, 2, 3, 100]

While it might be expected for compound objects like lists to have attributes and methods, what is sometimes unexpected is that in Python even simple data types have attached attributes and methods. For example, numerical types have a real and imag attribute that returns the real and imaginary part of the value, if viewed as a complex number:

In [ ]:
x = 4.5
print(x.real, "or", x.imag, 'i')
4.5 or 0.0 i

Methods are like attributes, except they are functions that you can call using opening and closing parentheses. For example, floating point numbers have a method called is_integer that checks whether the value is an integer:

In [ ]:
x = 4.5
x.is_integer()
Out[ ]:
False
In [ ]:
x = 4.0
x.is_integer()
Out[ ]:
True

When we say that everything in Python is an object, we really mean that everything is an object – even the attributes and methods of objects are themselves objects with their own type information:

In [ ]:
type(x.is_integer)
Out[ ]:
builtin_function_or_method

We'll find that the everything-is-object design choice of Python allows for some very convenient language constructs.

While this might seem somewhat confusing and irrelevant at first, please keep this in mind when we dive deeper into the semantics during the next few chapters.

Naming Variables: Keywords and Identifiers

Python Keywords

Keywords are the reserved words in Python.

We cannot use a keyword as a variable name, function name or any other identifier. They are used to define the syntax and structure of the Python language.

In Python, keywords are case sensitive.

There are 33 keywords in Python 3.7. This number can vary slightly in the course of time.

All the keywords except True, False and None are in lowercase and they must be written as it is. The list of all the keywords is given below.

Keywords in Python
False class finally is return
None continue for lambda try
True def from nonlocal while
and del global not with
as elif if or yield
assert else import pass
break except in raise

Python Identifiers

Rules for writing identifiers

  1. dentifiers can be a combination of letters in lowercase (a to z) or uppercase (A to Z) or digits (0 to 9) or an underscore _. Names like myClass, var_1 and print_this_to_screen, all are valid example.
  1. An identifier cannot start with a digit. 1variable is invalid, but variable1 is perfectly fine.
  1. Keywords cannot be used as identifiers.
In [ ]:
global = 1
  File "<ipython-input-1-3d177345d6e4>", line 1
    global = 1
           ^
SyntaxError: invalid syntax
  1. We cannot use special symbols like !, @, #, $, \% etc. in our identifier.
In [ ]:
a@ = 0
  File "<ipython-input-2-4d4a0e714c73>", line 1
    a@ = 0
       ^
SyntaxError: invalid syntax
  1. Identifier can be of any length.