© Lamy Jean-Baptiste 2021
L. Jean-BaptisteOntologies with Pythonhttps://doi.org/10.1007/978-1-4842-6552-9_2

2. The Python language: Adopt a snake!

Lamy Jean-Baptiste1  
(1)
Université Sorbonne Paris Nord, LIMICS, Sorbonne Université INSERM, UMR 1142, Bobigny, France
 

Python is a versatile and easy-to-learn programming language. It has been in existence for almost 30 years, but it remained quite confidential for many years and is now a big success—to the point of being one of the most widely taught programming languages today. The main advantage of Python is its simplicity and time saving for the user: with Python, I achieve in one day what I would program in three days in Java and a week in C. Python allows a significant gain of productivity.

Python is an open source software, and it is available for free. It runs on virtually all existing operating systems (Linux PC, Windows PC, Mac, Android, etc.). There are historically two versions of Python: version 2.x (no longer supported but still used by old programs) and version 3.x (currently supported and recommended). Owlready requires version 3.x, so we’ll use this one in this book. However, the differences between the two versions are minimal.

In this chapter, we will quickly introduce the basics of the Python language and its syntax. However, if you have no programming skill yet, we advise you to first consult a book entirely devoted to learning Python. On the contrary, if you already know the Python language, you can go directly to section 2.11 for installing Owlready.

2.1 Installing Python

Under Linux, almost all distributions offer packages for Python (often these packages will even be already installed). You can check that they are present in the package manager of your distribution and install the package python3 if necessary. Also, install the python3-pip and python3-idle packages if your distribution distinguishes them from the main python3 package.

On Windows, it is necessary to install Python. You can download it from the following address:

http://python.org/download/

On Mac OS, Python is probably already installed; you can verify it by running the command “python3 -v” in a terminal. Otherwise, please install it from the preceding website.

2.2 Starting Python

To program in Python, you can either use an integrated development environment (IDE) or use a text editor and a terminal. If you’re new to Python, the first option is probably the simplest; we suggest the IDLE environment that is usually installed with Python 3.

Python is an interpreted language, so it can be used in two different modes:
  • The “shell” mode, in which the computer interprets one by one the lines of code entered by the programmer, as they are entered. This mode is convenient for performing quick tests. The default “Shell” window opened by IDLE corresponds to this mode (see the following example). The “>>>” sign at the beginning of the line is Python’s command prompt: the interpreter prompts you to enter a new line of code.

Attention, in “shell” mode, the lines of code entered are not saved and will be lost when closing the terminal or IDLE!

../images/502592_1_En_2_Chapter/502592_1_En_2_Figa_HTML.jpg
  • The “program” mode, in which the user writes a multiline program, and then the computer executes the entire program. This mode allows you to perform complex programs. With IDLE, you can create a new program with the File ➤ New file menu. A new window will appear, in which you will write the program (see the following example). The file will then be saved (with the extension .py) and can be executed with the Run ➤ Run module menu (or by pressing the F5 key).

../images/502592_1_En_2_Chapter/502592_1_En_2_Figb_HTML.jpg
On Linux, you may prefer to use a text editor to enter programs (e.g., Emacs, Vi) and a terminal to execute them:
  • To have a “shell” mode, execute the command “python3” in the terminal:

[Bash prompt]#  python3
Python 3.7.1 (default, Oct 22 2018, 10:41:28)
[GCC 8.2.1 20180831] on linux
Type "help", "copyright", credits or "license" for more information.
>>>
To quit Python, press Ctrl+D.
  • To run a program, run the command “python3 file_name.py” in the terminal (obviously replacing file_name.py with the name of the file where you saved your program, with the path if necessary).

By convention, in this book, we will write short examples of Python code in the manner of the “shell” mode: the Python code is preceded by the command prompt “>>>”, while the eventual output displayed by these lines is displayed without this prefix, for example:
>>> print("Hello again!")
Hello again!
To execute this example, the “>>>” prompt should never be entered (neither in “shell” mode nor in “program” mode). Only the code following the prompt must be entered. When the command occupies multiple lines, Python adds “...” in “shell” mode, as in the following example:
>>> print(
... "Still here ?")
Still here ?

This is an “end of command” prompt. As before, the “...” should not be entered.

Longer code examples will be presented as programs, as follows:
# File file_name.py
print("It's me again!")
print("See you soon.")

The first line just indicates the filename; it does not have to be entered in the program.

Finally, in the lines of code, the ↲ character will be used at the end of a line to indicate a line break due to the limited width of the pages of this book. In this case, you do not have to go back to the line when you are programming, for example:
>>> x = "This is a very long text here, isn't it?"↲
+  "Indeed, it is."

2.3 Syntax

2.3.1 Comments

In Python, anything following the hash character “#” is a comment and is not taken into account by the Python interpreter. Comments are used to give guidance to programmers who will read the program, but ignored by the machine. Here is an example:
>>> # This text is a comment, and thus it is ignored by Python!

2.3.2 Writing on screen

The print() function is used to write on the screen (in the shell, or on the standard output in the “program” mode); we have already met it previously. It is possible to display several values separated by commas:
>>> print("My age is", 40)
My age is 40
The print() function can be omitted in the “shell” mode, but it is mandatory in the “program” mode.
>>> print(2 + 2)
4
>>> 2 + 2
4

2.3.3 Help

Python has a large number of predefined functions. In “shell” mode, the help() function is used to get help on a function, for example, for the print() function:
>>> help(print)

Then, in the “shell” mode, you may exit the man page by pressing the “Q” key on the keyboard.

2.3.4 Variables

A variable is a name to which a value is associated. Often, the value will only be known when the program is executed (e.g., when it is the result of a calculation).

The name of a variable must start with a letter or an underscore “_”, and it can contain letters, numbers, and underscores. Python 3 accepts accented characters in variable names, but spaces are forbidden.

In Python, variables do not need to be declared, and they are not typed. The same variable can therefore contain any type of data, and the type of its value can change during the program. The operator “=” is used to define (or redefine) the value of a variable; it can be read “takes the value of” (be careful, this is not the usual meaning of “=” in mathematics).
>>> age = 39
>>> print(age)
39
In computation, the names of the variables are replaced by their values:
>>> age + 1
40
The “=” operator can also be used to redefine the value of a variable. For example, to increase the value of the variable age by 1, we will do:
>>> age = age + 1
>>> age
40

2.3.5 Indentation

Indentation corresponds to the spaces to the left of the lines of code. Unlike most other programming languages where indentation is just a convention, in Python indentation is significant. Therefore, a bad indentation is a syntax error in Python! In particular, we should not add space on the left outside conditions and loops (which we will see later). The following example shows an indentation error:
>>>          age
  File "<stdin>", line 1
    age
    ^
IndentationError: unexpected indent

In addition, it is recommended that you do not mix spaces and tabs when indenting Python programs.

2.4 Main datatypes

Python can manipulate various datatypes: integers (abbreviated as int), real numbers (often called float), Unicode character strings (abbreviated as str), and booleans (true or false value, abbreviated as bool). The datatype of a variable does not have to be declared and may change during the execution of the program. Here are examples of various datatypes:
>>> age        = 31 # Integer
>>> weight     = 64.5 # Floating-point number
>>> name       = "Jean-Baptiste Lamy" # Character string
>>> teacher    = True  # Boolean
>>> student    = False # Boolean

2.4.1 Integer (int) and floating-point numbers (float)

Integers are numbers without a decimal part. There are no limits to integer values in Python.

Real numbers are usually represented by floating-point numbers in computer science (they are called “float” because the position of the comma is said to be floating: there can be many digits before the decimal part and few after or vice versa). A dot is used to indicate the decimal part, as in the following example:
>>> poids = 64.4

In Python, floats actually have a precision equivalent to “double” numbers found in many other programming languages (including C, C++, and Java).

Be careful, 10.0 is a float, while 10 is an integer.

The following table summarizes the main algebraic operations on numbers:

Algebraic operations

Examples

Addition

>>> 2 + 2

4

Subtraction

>>> 4 - 2

2

Multiplication

>>> 3 * 4

12

Division

>>> 10 / 3

3.3333333333333

Integer division

>>> 10 // 3

3

Power

>>> 3 ** 2

9

2.4.2 Booleans (bool)

Booleans can take two values, which are written True (true, integer value 1) and False (false, integer value 0) in Python.

2.4.3 Character strings (str)

Character strings are texts or portions of text. There is no limit on the number of characters (zero, one, or more). Strings are always enclosed in quotation marks (single or double; it is better to use double quotes because the single quotation mark is the same character as the apostrophe). In Python 3, all strings are Unicode and can thus include any character from any language.
>>> name = "Jean-Baptiste Lamy"
>>> empty_string = ""
To insert special characters in strings, use escape codes starting with a backslash. Here are the most common:

Special characters

Escape codes

Line break

Tab

Backslash

\

Simple quote

'

Double quote

"

In particular, on Windows, backslashes in filenames and paths must be doubled, for example, “C:\directory\file.py”.

Python also allows long character strings, which can span multiple lines and include quotation marks. A long string starts with three quotation marks and also ends with three quotation marks, as in the following example:
>>> long_string = """This character string is long
... and may contain line breaks and
... quotation marks " without problems.
... Backslashs \ must still be doubled, though."""

Single quotes can also be used for long character strings.

In Python, everything is an object, including strings. They thus have methods, which we can call with the pointed notation “object.method (parameters,...)”. The following table summarizes the main operations and methods on strings.

String operations

Examples

Get the length of a string (= the number of characters)

>>> s =Goodbye

>>> len(s)

7

Get a character in a string (be careful, the first character is zero and not one; negative numbers are counted from the end)

>>> s[0]

G# First character

>>> s[-1]

"e" # Last character

Get a part of the string

>>> s[0:4]

"Good"

Find if a string is included in another

>>> s.find("bye")

4 # Found in position 4

# (return -1 if not found)

Search from the end of the string (R stands for right)

>>> s.rfind("o")

2 # Found in position 2

# (return -1 if not found)

Split a string according to a separator

>>> "alpha;beta;gamma".↲ split(";")

["alpha", "beta", "gamma"]

Cut a string according to white spaces (spaces, line breaks, and tabs)

>>> "alpha beta gamma".↲split()

["alpha", "beta", "gamma"]

Replace a part of a string by another string

>>> "Come here!".↲replace("here", "there")

"Come there!"

Concatenate two strings (= put them end to end); be careful you have to add a space if you want one

>>> "JB" + "LAMY"

"JBLAMY"

Format a string with values

>>> last_name = "LAMY"

>>> first_name = "JB"

>>> "Hello %s!" %↲ first_name

"Hello JB!"

>>> "Hello %s %s!" %↲ (first_name, last_name)

"Hello JB LAMY!"

>>> rate = 90

>>> "Success rate: %s %%"↲% rate

"Success rate: 90 %"

2.4.4 Lists (list)

Lists contain zero, one, or more elements (they are similar to arrays in other programming languages, but their size can vary). The elements can be of different types (integers, strings, etc.). The lists are created with square brackets; the elements are given inside the square brackets and separated by commas, for example:
>>> my_list    = [0, "Lamy", True]
>>> empty_list = [ ]

In a list of n elements, the elements are numbered from zero to n − 1. By convention, the lists often receive a plural variable name, for example, “animals” for a list of animals.

Python lists are also objects. The following table summarizes the main operations and methods available on lists.

List operations

Examples

Create a list

>>> animals = ["elephant",

...            "giraffe",

...            "rhinoceros",

...            "gazelle"]

Get the length of a list (= the number of elements)

>>> len(animals)

4

Get an element from the list (be careful, lists are numbered from zero and not one)

>>> animals[0]

"elephant" # First

>>> animals[-1]

"gazelle" # Last

Get a part of the list

>>> animals[0:2]

["elephant", "giraffe"]

Add an element at the end

>>> animals.append("lion")

Add an element to a given position (0: first position, etc.)

>>> animals.insert(0, "lynx")

Concatenate two lists

>>> [1, 2] + [3, 4, 5]

[1, 2, 3, 4, 5]

Remove a given element

>>> animals.↲remove("gazelle")

Remove the element at a given position

>>> del animals[-2]

Find if an element is present in a list

>>> "lion" in animals

True

Sort a list (ascending/alphabetical order by default)

>>> animals.sort()

Get the highest element from a list, or the lowest

>>> max([2, 1, 4, 3])

4

>>> min([2, 1, 4, 3])

1

2.4.5 Tuples (tuple)

Tuples are very similar to lists, the difference being that they are not modifiable. Tuples are written in parentheses, instead of square brackets:
>>> triple               = (1, 2, 3)
>>> pair                 = (1, 2)
>>> single_element_tuple = (1,) # Do not forget the comma here!

2.4.6 Dictionaries (dict and defaultdict)

A dictionary (or associative array, hashtable, or hashmap) maps keys to values. For example, a dictionary can match a word with its definition (hence the dictionary name). A dictionary is created with braces, in which are placed zero, one, or more “key: value” pairs, separated by “,”. For example (remember that the “...” at the beginning of the lines are part of the Python prompt and should not be entered by the programmer):
>>> my_dict = {
...    "fruit"  : "a plant food with a sweet taste",
...    "apple"  : "a fleshy fruit with a red or green skin",
...    "orange" : "a juicy fruit with an orange skin",
... }

In the previous example, the keys are “fruit”, “apple”, and “orange”, and the values are the definitions. Each key has one and only one value.

The keys of a dictionary must be immutable (i.e., nonmodifiable). Therefore, we cannot use a list as a key (a tuple is commonly used instead).

Python dictionaries are also objects. The following table summarizes the main operations and methods on dictionaries.

Dict operations

Examples

Get the number of keys (or values) in the dictionary

>>> len(my_dict)

3

Get the value associated with a key

>>> my_dict["apple"]

"a fleshy fruit with a red or green skin"

Add or modify the value for a given key

>>> my_dict["clef"] = "value"

Delete a key (and its associated value)

>>> del my_dict["clef"]

Search if a key is present in the dictionary

>>> "apple" in my_dict

True

Recover all the keys

>>> for key in my_dict: ...

or

>>> keys = list(my_dict.↲keys())

Recover all the values

>>> for value in my_dict.↲values(): ...

or

>>> values = list(my_dict.↲values())

Collect all (keys, values) pairs (as tuples)

>>> for key, value in↲my_dict.items(): ...

or

>>> pairs = list(my_dict.↲items())

Python also offers a default dictionary, called defaultdict, which is often useful. It is defined in the collections module (we will see modules later; in the following example, the first line corresponds to the import of the module; see 2.10.1). When you get a value from a default dictionary and the key is not present in the dictionary, it is automatically added with a default value. When it is created, the defaultdict takes a parameter that is the default datatype (it can be a datatype, a function, or a class, which we will see later).

The following example creates a defaultdict with the int type. The default value is the integer 0.
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> d["new_key"]
0
>>> d["new_key"] = d["new_key"] + 1
>>> d["new_key"]
1
>>> d["new_key"] = d["new_key"] + 1
>>> d["new_key"]
2
Here is a second example that creates a defaultdict with the list type. The default value is therefore an empty list. A defaultdict of list is commonly used when each key may be mapped to several values (i.e., a list of values).
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> d["new_key"]
[]
>>> d["new_key"].append("a")
>>> d["new_key"]
['a']
>>> d["new_key"].append("b")
>>> d["new_key"]
['a', 'b']

2.4.7 Sets (set)

Sets are very close to lists from a functionality point of view, and to dictionaries from an implementation point of view. Unlike lists, elements are not ordered, and there cannot be a duplicate. Sets are written in braces, like dictionaries, but with elements instead of “key: value” pairs:
>>> my_set = {1, 2, 1, 3}
>>> len(my_set)
3

Note that the duplicate (the second 1) has been removed.

The empty set must be created with the set() function, to avoid confusion with an empty dictionary (which is noted as {}):
>>> empty_set = set()

The add() method allows you to add an element to a set (it replaces the append() method of lists) and the remove() method to remove an element.

Classical set operations (union, intersection, etc.) are available via methods and operators (“&” for the intersection, “|” for the union). Immutable sets (frozenset) are used as keys in dictionaries, instead of sets. They are to sets what tuples are to lists.

2.4.8 Files (open)

Files are open with the open() function:
>>> my_file = open("path/filename.ext", "r")
The second parameter is the “mode”; it can be one of the following values:
  • “r” to read a text file (default value)

  • “w” to write a text file

  • “rb” to read a binary file

  • “wb” to write a binary file

Opening a file for writing automatically creates the file if it does not exist and overwrites it otherwise. Python handles the conversion of line breaks (Unix/Windows/Mac) and the encoding of text files (UTF-8 by default).

File operations

Examples

Read the whole content of the file, as a string

>>> content = my_file.read()

Write to a file

>>> my_file.write("content")

Close the file (automatically called when the file object is destroyed by Python)

>>> my_file.close()

2.4.9 Conversion between datatypes

It is sometimes necessary to convert from one type of data to another. The int(), float(), str(), list(), tuple(), set(), and frozenset() functions allow converting a value to an integer, float, string, list, tuple, set, or immutable set, respectively.

Convert to

Syntax

Integer

int(x)

Float

float(x)

Boolean

bool(x)

List

list(x)

Tuple

tuple(x)

Set

set(x)

Immutable set

frozenset(x)

Dictionary

dict(x)

# x is of the form [(key1, value1), (key2, value2)...]

String

str(x)  # String for displaying to the user

repr(x) # String for displaying to the programmer

The following example converts the integer 8 to a string:
>>> str(8)
'8'

2.5 Conditions (if)

The conditions allow executing commands only in certain situations, which will be determined at the execution of the program. The general Python syntax for conditions is as follows:
if condition1:
     instruction executed if condition1 is true
     instruction executed if condition1 is true...
elif condition2:
     instruction executed if condition1 is false
     and condition2 is true...
else:
     instruction executed if condition1
     and condition2 are false...
continuation of the program
(executed whether the conditions are true or false)

elif is the contraction of else and if. The “elif” and “else” parts are optional, and several “elif” parts may be present. The indentation (i.e., the white space at the beginning of the line) is important because it indicates where the condition ends. The number of spaces is the choice of the programmer but must remain constant, and it is recommended to avoid mixing space characters and tabs.

The condition can use the standard comparison operators:
  • < (less than)

  • > (greater than)

  • <= (less than or equal to)

  • >= (greater than or equal to)

  • == (equal to, not to be confused with the simple “=” used for defining variables)

  • != (different from)

  • is (test the identity between two objects)

Logical operators “and”, “or”, and “not” can be used to combine several conditions together, as in the following example:
>>> if (age > 18) and (age < 65):
...     print("You are an adult.")
When there is only one instruction to execute, it is possible to put everything on a single line:
>>> if age >= 65: print("You are an elderly person.")
Conditions can be nested, using multiple levels of indentation:
>>> if age == 0:
...      print("You are a newborn.")
...      if weight > 10.0:
...           print("I think there is an error in the weight!")

2.6 Loops (for)

A loop makes it possible to execute the same commands several times. In Python, loops traverse a list and execute a series of instructions for each element of the list (this is a type of loop often called “for each” in other programming languages). The current element is placed in a variable of your choice. The general syntax of the for loop is as follows:
for variable in my_list:
     if conditions1: continue # Move to the next item in the list
     if conditions2: break    # Stop the loop
     repeated instructions...
else:
     instructions executed only if the loop went all the way
     (i.e. no break was encountered)
continuation of the program (executed once)

The continue instruction interrupts the current iteration and immediately moves to the next element. The break instruction interrupts the loop and exits immediately from the loop. Finally, the else part is executed only if the loop has gone to the end (i.e., it has not been interrupted by break). Of course, the presence of continue, break, and else is not mandatory in a given loop.

The iterated list can be a variable containing a list, but also a string of characters (the loop then iterates over each character of the string), a set (the loop iterates over the elements of the set, in an arbitrary order), a dictionary (the loop iterates over the keys of the dictionary), and so on. It can also be a list of index generated with the range() function:
>>> range(4)

Be careful, the range() function of Python has nothing to do with the “range” of an OWL property, which we will see later!

Here is an example of a loop. It considers a list of animal names and displays one animal per line:
>>> animals = ["elephant", "zebra", "rhinoceros", "dolphin"]
>>> for animal in animals:
...      print(animal)
elephant
zebra
rhinoceros
dolphin
If you want to also display the number of each animal in the list, we can use range():
>>> for i in range(len(animals)):
...      print(i, animals[i])
0 elephant
1 zebra
2 rhinoceros
3 dolphin
Loops can also be integrated in the definition of a list: they are comprehension lists. Here is an example:
>>> integers      = [1, 2, 3]
>>> even_integers = [2 * i for i in integers]
>>> even_integers
[2, 4, 6]
This comprehension list is identical to the list created by the following loop:
>>> even_integers2 = []
>>> for i in integers:
...     even_integers2.append(2 * i)
>>> even_integers2
[2, 4, 6]
Similarly, Python proposes comprehension sets and dictionaries, for example:
>>> twofold = { i: 2 * i for i in integers }
>>> twofold
{1: 2, 2: 4, 3: 6}
>>> twofold[2]
4
When one wishes to loop on several lists, two cases can appear:
  • The lists are not paired. In this case, we will use nested loops, as in the following example:

>>> animals = ["elephant", "zebra", "rhinoceros",↲ "dolphin"]
>>> environments = ["savanna", "forest", "river"]
>>> for animal in animals:
...     for environment in environments:
...         print("a", animal, "in the", environment)
a elephant in the savanna
a elephant in the forest
a elephant in the river
a zebra in the savanna
a zebra in the forest
a zebra in the river
a rhinoceros in the savanna
a rhinoceros in the forest
a rhinoceros in the river
a dolphin in the savanna
a dolphin in the forest
a dolphin in the river
  • The lists are paired, two by two (or three by three, etc., that is to say that the first element of list 1 is associated with the first element of list 2, the second element of list 1 with the second element in list 2, etc.). The zip() function allows you to loop on two (or more) paired lists. In the following example, we have a list of animals and a list of environments paired, that is, animal #1 goes with environment #1, animal #2 with environment #2, and so on:

>>> animals = ["elephant", "zebra", "rhinoceros",↲ "dolphin"]
>>> environments = ["savanna", "forest", "savanna",↲ "river"]
>>> for animal, environment in zip(animals,↲ environments):
...      print("a", animal, "live in the", environment)
a elephant live in the savanna
a zebra live in the forest
a rhinoceros live in the savanna
a dolphin live in the river

2.7 Generators

A generator makes it possible to browse a series of elements (in the manner of a list); however, it does not store in memory all the elements like a list: the generator produces the elements one by one, and these must be immediately processed (e.g., using a loop). The generator therefore allows a gain in performance, especially when working on large volumes of data. This is why a number of Owlready methods return generators and not lists.

Generators can also be converted into lists with the list() function, for example, for display, as follows:
>>> print(list(my_generator))
On the contrary, to loop on a generator, it is best not to use list() to improve performance, as follows:
>>> for x in my_generator: print(x)

2.8 Functions (def)

Functions are used to define a group of instructions (or “subroutine”), with a view to executing it several times at different places of the main program. This group of instructions can receive parameters: these parameters will be passed to the call of the function and will be available inside the function as local variables. The functions are created with the def statement whose general syntax is:
def function_name(parameter1, parameter2 = default_value,...):
     function body
     return return_value

Functions can receive multiple parameters, and each can have a default value.

The return statement indicates the return value of the function, and interrupts it.

Then, the function can be called with parentheses (parentheses are mandatory, even if there are no parameters):
returned_value = function_name(parameter1_value, parameter2_value)
returned_value = my_function_with_no_parameter()
Here is a simple example of a function:
>>> def twofold(x):
...      return x * 2
>>> twofold(3)
6
>>> twofold("bla")
'blabla'

Note that the function parameters are not typed. That’s why in the previous example we were able to use our twofold() function on both an integer and a string.

When calling the function, the parameters can be named, which allows passing them in any order:
returned_value = function_name(parameter2 = parameter2_value,
                               parameter1 = parameter1_value)
A function can also have a variable number of parameters:
def my_function(*args, **kargs):
    function body
    return returned_value
args (arguments) will receive a tuple with the values of non-named parameters, and kargs (keyword arguments) a dictionary with named parameters. Here is an example:
>>> def function_with_variable_parameters(*args, **kargs):
...      print(args, kargs)
>>> function_with_variable_parameters(1, 2, 3, extra_param = 4)
(1, 2, 3) { "extra_param": 4 }
This syntax can also be used when calling a function:
>>> kargs = { "parameter1": 1, "parameter2": 2 }
>>> function(**kargs)
# equivalent to function(parameter1 = 1, parameter2 = 2)

2.9 Classes (class)

2.9.1 Classes and instances

Classes are the basis of object-oriented programming. A class represents a template for creating objects, for example, we may have a class for creating animals or books. A class can also be seen as a general category of objects, for example, a “book” is a general category, and many different books exist with different titles, authors, and so on.

By convention, class names always start with a capital letter (e.g., “Book”). The class defines the available properties for each object of this class (e.g., for the class Book: title, author, and price) and the methods that can be applied to each object (e.g., for the class Book: format a book citation).

The class will then create objects of the class, called “instances”, for example, “The Lord of the Rings” and “Nine Princes in Amber” will be two instances of the same “Book” class. The class therefore makes it possible to “factorize” the part common to the instances: the property definitions and the methods, while the values of the properties are specific to each instance.

In Python, classes are created with the class statement. The methods are created inside classes with the def statement (as for functions); the first parameter represents the object on which the method is applied (it is called self by convention; it is equivalent to the keyword this in Java or C++ but appears explicitly in the method parameters). Attributes are not typed, just like variables. They are defined by giving them a value, with the syntax “self.attribute_name = value”.

The general syntax of the class statement is:
class my_class(parent_class1, parent_class2,...):
     class_attribute_name = value
     def __init__(self, parameters...): # constructor
         self.object_attribute_name = value
     def method1(self, parameters...):
         method_body
         return returned_value
     def method2(self, parameters...):
         method_body
         return returned_value
When a class is empty (it does not contain any method), it is necessary to add a pass statement, to indicate it to Python:
class my_empty_class(parent_class1, parent_class2,...):
    pass

In the body of methods, the “self” active object must always be specified when one wants to obtain or modify its attributes (self.attribute) or to call its methods (self.method(parameters...)).

__init__() is a special method called a “constructor”. If present, the constructor is automatically called when a new instance is created. The constructor can receive parameters, whose values will be given when the instance is created.

Here is an example of a definition of the “Book” class:
>>> class Book(object):
...     def __init__(self, title, author, price):
...         self.title  = title
...         self.author = author
...         self.price  = price
...     def format_citation(self):
...         return '%s' by %s (price: %s€) % (self.title,↲
                self.author, self.price)

In the previous definition, we defined the Book class from the object class, which is the most general class in Python.

Then, to create an instance of a class, the class is called in the manner of a function. Any parameters will be passed to the __init__() constructor.
my_object = my_class(constructor_parameters...)
The dotted notation is used to access the attributes and methods of the object:
print(my_object.attribute)
my_object.attribute = value
my_object.method(parameters...)
The self parameter is never given when calling the method on an instance. The previous call is equivalent to
my_object_class.method(my_object, parameters...)
For example, we can create one or more instances of the Book class, obtain their property values or modify them, and call their methods:
>>> ldr = Book("The Lord of the Rings", "JRR Tolkien", 24)
>>> npa = Book("Nine Princes in Amber", "R Zelazny", 12)
>>> npa.author
'R Zelazny'
>>> npa.price = 10
>>> npa.format_citation()
"'Nine Princes in Amber' by R Zelazny (price: 10€)"

2.9.2 Inheritance

Inheritance is a fundamental mechanism in object-oriented programming. This mechanism allows you to create new classes that share a similar blueprint to a given class, that is to say, to define subcategories within a class. For example, comics are a particular subcategory of books: the Comic class is a subclass that inherits from Book. The general class (here, Book) is called the “superclass” or “parent class”, and the more specific class (here, Comic) is called the “subclass” or the “child class”.

The child class inherits all the attributes and methods of its parent class(es): just like the instances of the Book class, those of the Comic class have a title, an author, and a price (attributes), and it is possible to format a citation (method). However, the child class may have additional attributes and methods. For example, a comic book is characterized by its author (or scriptwriter) but also by its illustrator: we can therefore add an “illustrator” attribute to the Comic class. Inheritance makes it possible to “factorize” the source code and to simplify it by avoiding repeating the attributes and methods common to the parent class and its children classes.

In addition, it is possible to redefine the methods of the parent class in the child class. For example, the constructor of the Comic class can be redefined to accept an additional “illustrator” parameter, and the format_citation() method can be redefined to display the illustrator name. When redefining a method, it is possible to delegate to the parent class method by calling the parent class using the keyword super(), as in the following example:
class my_child_class(my_parent_class1, my_parent_class2,...):
    def my_method(self, parameters...):
         parent_returned_value = super().my_method(parameters...)
         additional child class method body
         return child_return_value
The following example defines the Comic class, inheriting from the Book class:
>>> class Comic(Book):
...     def __init__(self, title, author, illustrator, price):
...         super().__init__(title, author, price)
...         self.illustrator = illustrator
...     def format_citation(self):
...         return "'%s' written by %s and illustrated by %s↲
(price: %s€)" % (self.title, self.author, self.illustrator,↲
self.price)

The constructor method __init__() and the format_citation() method have been redefined in the Comic child class. The new constructor definition supports the illustrator attribute and delegates to the parent class method for managing the title, author, and price attributes.

The following example creates an instance of Comic:
>>> re = Comic("Return to the Earth", "Yves Ferry",↲
"Manu Larcenet", 10)
>>> re.format_citation()
"'Return to the Earth' written by Yves Ferry and illustrated by↲
Manu Larcenet (price: 10€)"

Note that we can call the format_citation() method without knowing if the object on which we call it is a Book or a Comic. Python will automatically choose the right method, depending on the class of the object. This mechanism is called polymorphism.

The following example goes through the three instances we created and displays their citation. The x variable sometimes contains a Book and sometimes a Comic, and the format_citation() method is called without knowing the exact class of the object x.
>>> for x in [ldr, npa, re]:
...      print(x.format_citation())
"'The Lord of the Rings' by JRR Tolkien (price: 24€)"
"'Nine Princes in Amber' by R Zelazny (price: 10€)"
"'Return to the Earth' written by Yves Ferry and illustrated↲
by Manu Larcenet (price: 10€)"

Python also allows multiple inheritance: several parent classes can be given when defining a child class, separated by commas.

2.9.3 Special method names

In Python, method names with two underscores at the beginning and end are special methods. Here are the main ones:
  • __init__(self, parameters...): Constructor

  • __del__(self): Destructor

  • __repr__(self): Returns a string for displaying to the programmer

  • __str__(self): Returns a string for displaying to the final user

2.9.4 Functions and operators for object-oriented programming

The following three attributes and functions can be used to analyze the relationships between objects and/or classes:
  • object.__class__ returns the class or the type of an object, for example:

>>> ldr.__class__
<class 'Book'>
>>> "blabla".__class__
<class 'str'>
  • isinstance(object, Class) tests whether the given object belongs to the given class (including child classes, grandchild, etc.), for example:

>>> isinstance(ldr, Book)
True
>>> isinstance(ldr, Comic)
False
>>> isinstance(re, Book)
True
>>> isinstance(re, Comic)
True
  • issubclass(Class, parent_class) tests whether the given class inherits from parent_class, for example:

>>> issubclass(Comic, Book)
True
>>> issubclass(Book, Comic)
False
The is operator allows testing whether two objects are the same:
>>> ldr is ldr
True
>>> ldr is npa
False
Finally, the following functions are used to manipulate the attributes of an object when the name of the attribute is not known at the time of writing the program, but is available during execution in a variable (as a string):
  • hasattr(object, attribute_name) tests whether the object has an attribute named attribute_name.

  • getattr(object, attribute_name) returns the value of the attribute named attribute_name for the object.

  • setattr(object, attribute_name, value) defines the value of the attribute named attribute_name for the object.

  • delattr(object, attribute_name) deletes the attribute named attribute_name from the object.

>>> attribute_name = "author"
>>> hasattr(ldr, attribute_name)
True
>>> getattr(ldr, attribute_name)
'JRR Tolkien'

These methods are particularly useful for introspection, that is, for manipulating objects in a generic way, without knowing their class or their attributes.

2.10 Python modules

Python modules define additional functions and classes in a specific domain (such as mathematics, bioinformatics, 3D graphic, etc.). Owlready2 is an example of Python module. The functions and classes contained in these modules are not available by default in Python; it is mandatory to import the corresponding modules before accessing and using them.

2.10.1 Importing a module

There are two ways for importing a module in Python:
  1. 1.
    Importation of the module with its name. With this method, it is necessary to mention the name of the module followed by a “.” in front of each of the functions and classes of the module. Here is an example with the math module:
    >>> import math
    >>> math.cos(0.0)
    1.0
     
  2. 2.

    Import the contents of the module. With this method, the functions and classes of the module can be used directly, without having to mention the name of the module at each call. On the other hand, if several modules define functions or classes having the same name, this could be problematic: in this case, the last import will overwrite the previous one. Here is another example with the math module:

     
>>> from math import *
>>> cos(0.0)
1.0

The Python language includes a large number of “standard” modules, which are installed with Python itself. The official Python documentation describes each of these modules; it is available online at the following address:

https://docs.python.org/3/py-modindex.html

Other modules can be installed from PyPI (Python Package Index), available at

https://pypi.org/

2.10.2 Installing additional modules

The “pip3” tool allows downloading, installing, and updating automatically Python 3 modules over the Internet from PyPI. This tool can be used on the shell command line (under Unix/Mac) or in the MS-DOS command prompt (on Windows). The following command line installs a Python module (or update it, if it is already installed):
pip3 install -U name_of_the_module_to_install
It is preferable to install the modules as “root” (or superuser, under Linux/Mac) or “administrator” (under Windows), so that they are available to all users. However, this is not an obligation: if you do not have the necessary rights for a global installation, you can install the modules only for the current user, with the “--user” parameter. The following command line installs a module for the current user:
pip3 install -U --user name_of_the_module_to_install

2.11 Installing Owlready2

Owlready version 2 can be installed from the Internet with the “pip3” tool; the corresponding module is called “owlready2” (be careful not to forget the version number 2).

In addition, Owlready offers a version optimized in Cython, a language derived from Python compiling in code C. In order to benefit from this optimized version, it is necessary to install beforehand the “cython” module. However, if the installation of Cython went wrong, or if you do not have a C compiler (especially on Windows), you can install Owlready without Cython, at the price of (slightly) reduced performances when loading ontologies.

Finally, the following Python modules will also be used in the rest of the book: “Flask”, “MyGene”, and “RDFlib”.

2.11.1 Installing Owlready2 from terminal

The following commands can be used to install Owlready2 and the other modules in a terminal (Bash terminal under Linux/Mac, DOS command-line interface under Windows):
pip3 install -U cython
pip3 install -U owlready2 Flask mygene rdflib
If you do not have root or administrator privileges, use the following commands to install the modules for the active user:
pip3 install -U --user cython
pip3 install -U --user owlready2 Flask mygene rdflib

2.11.2 Installing Owlready2 from IDLE or Spyder (or any Python shell)

You can use the following Python commands to install Owlready2 from any Python 3.7.x console, including those found in the integrated development environment, including IDLE or Spyder3:
>>> import pip.__main__
>>> pip.__main__._main(["install", "-U", "--user", "cython")
>>> pip.__main__._main(["install", "-U", "--user", "owlready2", "rdflib")
>>> pip.__main__._main(["install", "-U", "--user", "Flask", "mygene")

2.11.3 Manual installation of Owlready2

In case of troubles, Owlready2 can also be installed manually in five steps:
  1. 1.

    Download the compressed sources from PyPI: https://pypi.org/project/Owlready2/#files.

     
  2. 2.

    Decompress the compressed sources, for example, under “C:” under Windows.

     
  3. 3.

    The source directory is named “Owlready2-0.xx” where “xx” is the version number (e.g., “Owlready2-0.25”). Rename this directory as “owlready2”, for example, “C:owlready2”.

     
  4. 4.
    Add the directory containing the source directory (“C:” in our example) in your PYTHONPATH; this can be done in Python as follows (NB: do not forget to double any backslash!):
    >>> import sys
    >>> sys.path.append("C:\")
     
  5. 5.

    You can now import Owlready2!

     
>>> import owlready2

2.12 Summary

In this chapter, we have seen how to perform basic programming in Python, including the language syntax, control structures such as conditions and loops, and object-oriented programming. We also reviewed the main Python datatypes, such as character strings or lists. Finally, we have seen how to install Python modules and in particular Owlready and the other modules needed for the examples in the rest of this book.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.193.172