Python types

This post is part of the Python Crash Course series. The chronological order on how to read the articles is to be found on the agenda.

In python you can manipulate different objects. If you take your pocket calculator, you might have mostly played around with integers and floating numbers – e.g. when performing additions and adding numbers together. Python extends those capabilities – not only allowing you to manipulate integers – but also to interact with a variety of different objects/types.

Short example

Let’s create a variable a and check its type:

zsh> python
>>> a = 42
>>> type(a)
<class `ìnt`>

You can see that a is of type int – which refers to integers.

Note: to learn how to start python on the terminal and to interact with it, see: python-via-command-line.

The different built-in types

By default, python provides different types which are already built-in. See: Built-in Types.

All of them possess their own associated methods so you can perform operations on them – e.g. integers additions etc.:

The most important and mainly used are: int, bool, list, tuple, str, dict and set.

type() vs. isinstance() vs is

There are situations where you want to check if the object you are dealing with is of a specific type. You can do it using the isinstance() method:

zsh> python
>>> isinstance("my_string", str)
True
>>> isinstance(42.0, int)
False

You could have also used the following:

>>> type(42.0) == float
True

However, there are differences between the both:

(1) From a design perspective, it is better to use == to check the value of a variable, not its type.

(2) To compare types, isinstance() is expected to be slightly faster, even though negligible on the latest python versions:

zsh> python
>>> from timeit import timeit
>>> timeit("isinstance(42.0, float)")
0.06043211100040935
>>> timeit("42.0 == float")
0.07633306799834827

(3) Sometime you do not want to compare if the object is strictly of a specific type but rather if it behaves like so or inherits its properties.

For instance, a str object has some methods that allow us to perform specific operations on it, like turning the text into uppercase:

zsh> python
>>> "This is my string".upper()
'THIS IS MY STRING'

Let’s now imagine that you want to create your own str type which inherits the str properties – such as the capacity to change the text case via upper() or lower() – but supplemented with your own custom methods:

zsh> python
>>> my_custom_str = ExtendedString("foo")

This custom type of yours is still to be considered as a str as it inherits the main properties of the str type:

>>>  my_custom_str.upper()
"FOO"

However, python sees different:

>>> type(my_custom_str) is str
False
>>> type(my_custom_str) == str
False
>>> isinstance(my_custom_str, str)
True

What is important to remember here is that isinstance() checks if my_custom_str is – overall – a subclass of str (it is, because ExtendedString inherits from str).

On the other hand, is or == check if my_custom_str is an instance of str (it is not directly the case, because it is – strictly speaking – an instance of ExtendedString).

Note: As for the difference between is and ==, is will return True is two variables point to the same object in memory while == returns True if the values hold by the variables are equal.

zsh> python
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a == b # values are equal
True
>>> a is b # but it's 2 different object
False
>>> a = b # a becomes b
>>> a is b
True
>>> b.append(4) # thus, if b changes
>>> b
[1, 2, 3, 4]
>>> a
[1, 2, 3, 4] # a changes

In practice, you can use the above concept e.g. to surcharge and add your strings the possibility to turn your texts into Spongemock case. You will have to extend and add this functionality by yourself as this feature is not natively present:

class ExtendedString(str):

    def spongebob(self) -> str:
        return "".join(
            char.upper() if i%2 == 0 else char.lower()
            for i, char in enumerate(self.__str__())
        )

You can imagine a following usage:

zsh> my_str = ExtendedString("The cake is a lie")
zsh> my_str.spongebob()
ThE CaKe iS A LiE

Going further about inheritance

If you go upstream, you can see that str itself inherits from Sequence. Thus, all str objects are also of type Sequence:

>>> from collections.abc import Sequence
>>> my_str = "foo"
>>> isinstance(my_str, str)
True
>>> isinstance(my_str, Sequence)
True

However, going up the stream even further – by winding the links all the way up – you will ultimately notice that all python types inherits from the catch-all python object:

>>> isinstance(my_str, object)
True
>>> isinstance(42, object)
True

Data vs. Common Classes

In python you can also create your own types using the dataclasses module:

from dataclasses import dataclass

@dataclass
class Point():
    x: float
    y: float

The main difference between common classes – like the ExtendedString one previously created – and data classes lies in the fact that data classes are not expected to contain any logic or methods.

Data classes are strictly geared toward storing data, not performing operation on it.

Python files

This post is part of the Python Crash Course series. The chronological order on how to read the articles is to be found on the agenda.

In the previous post (see python-via-command-line) we have interacted with python and wrote our very first python instructions.

However, this stateless way of using python is not very handy as – once the session is over – the lines of code cannot be accessed anymore.

The solution is to write our code in files. Instructions can be saved in python files. A python file is just an ordinary file that ends with the .py extension.

Generic python file

The general template for your python files is as follow:

"""
Few lines describing what your file
is useful for (optional but good practice).
"""

if __name__ == "__main__":
    # your instructions go there
    # these are just inline-comments
    # that are going to be ignored.
    # ...
    # PS. indentations are important.

For instance, here are the content of a file I named first_python_script.py:

"""
Short script containing my very first
Python instructions.
"""

if __name__ == "__main__":
    a = 41
    b = 1
    print(a+b)
    print("foo")

Executing the Python file

You can then tell python to execute your script via a command line instruction in the terminal:

zsh> python path/to/your/file/filename.py

Here is what I obtain after I have run the following command:

zsh> python ./first_python_script.py
42
foo

Note: you can write python files in a text editor – even on Microsoft Word. However, there is some special softwares on the market that help you to write code. They provide autocompletion, coloration and a lot of other useful features. You can check https://code.visualstudio.com/.

What comes next?

You have python installed in your system.

You can interact with python and execute python code; either via command lines via terminal prompts or running python scripts containing your python instructions.

It’s now time to deep-dive into the python syntax and explore the possibilities offered by this programming language.

Python via command line

This post is part of the Python Crash Course series. The chronological order on how to read the articles is to be found on the agenda.

In the previous post (see python-as-a-program) we have installed python. It’s now time to play around with it.

First, make sure python is installed:

zsh> python --version
Python 3.11.4 # your version may differ

Launch the program:

zsh> python
>>>

Note: see how the terminal prompt has changed. This shows you are now within the python program.

It’s all fun and games

We are now free to play around the way we like:

>>> 2+2
4
>>> my_string = "hello world!"
>>> print(my_string)
hello world!
>>> a = 4
>>> b = 5
>>> a*b
20
>>> my_number = 42
>>> my_number += 1
>>> print(my_number)
43

When you have had enough, you can simply write quit() and then hit Enter to call the exiting method:

>>> quit()

Note: you have to press Enter for your inline-command to be executed. Outputs are displayed on the next lines before the terminal handovers the process back to you.

Until you get stuck

It might happen you sometime get stuck with your program endlessly looping, performing never ending computations in the background.

This is the case if you have a while loop with no exit conditions:

>>> while True:
...    print("foo")
...
foo
foo
foo
foo
^C
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

You can interrupt such never-ending states by sending an exit signal. This is done by pressing Control + C.

Where to go now

By now, you have Python installed and you can run it in your terminal.

It’s a good start but not really convenient so far: after you have exited the program, all your instructions are gone.

It might be ok if you just want to play around. However, we want to be able to save our instructions so we can start building up on it next time we resume back to work.

What you want is to start writing your code into files so your code can actually be saved and retrieved after the session has ended.

This is what we gonna learn in the next chapter: python-files.

Python as a program

This post is part of the Python Crash Course series. The chronological order on how to read the articles is to be found on the agenda.

Like any other softwares

Like any other software, Python is a program that can be launched via the Terminal.

For instance, you can perfectly start a web browser session via the terminal:

zsh> open -a "Google Chrome" https://olivierbenard.fr

Same goes for Python:

zsh> python
>>> 2+2
4
>>> quit()

Software updates

Python is constantly updated; you can check the active releases and deprecated versions from the official page: https://www.python.org/downloads/.

An overview of the status for the different versions is accessible here: https://devguide.python.org/versions/.

Each version brings new functionalities to the code and correct existing bugs. Like a castle of cards, a constant improvement is going on.

For instance, the new 3.8 version brought multiple interesting features on the table such as the walrus operator and positional parameters.

A more extended view is given here: https://docs.python.org/3/whatsnew/3.8.html.

To track down each version – by convention – we use an incrementing sequence of numbers. More on that here: https://en.wikipedia.org/wiki/Software_versioning.

You can check the current installed version you might have on your system:

zsh> python --version
Python 3.11.4

As you can see, the semantic versioning has 3 components: 3.11.4 (major, minor and patch respectively).

You can have multiple python versions installed on your system. More on that here: pyenv-python-version-manager.

But that’s too much information, let’s leave it for now.

Python installation

To install python, simply pick the version you want from the official page and follow the instructions: https://www.python.org/downloads/.

I recommend going for the latest stable released version (3.12.1 at this time of writing).

Now that you have python installed, let’s start playing with it: python-via-command-line.