Aller au contenu

Syntaxes de base

Introduction

La syntaxe de Python reprend des notions familières aux développeurs C# : variables, expressions, traitements conditionnels et itératifs, fonctions, etc. Elle se distingue par des instructions dont l'écriture est plus concise et par certaines règles propres à ce langage, qu'il est nécessaire de connaître avant de commencer à développer. Ce chapitre en présente une vue d'ensemble ; chaque section est détaillée dans un chapître qui lui est consacré.

Les instructions ne nécessitent pas de point-virgule final, les blocs sont délimités par l'indentation et les variables peuvent être utilisées sans déclaration préalable de leur type. Ces différences rendent le code compact, mais demandent de nouvelles habitudes de lecture et d'écriture.

Les instructions

En Python, une instruction se termine généralement à la fin de la ligne. Il n'est pas nécessaire d'ajouter un point-virgule.

En C# :

int quantity = 3;
decimal unitPrice = 12.50m;
Console.WriteLine(quantity);

En Python :

quantity = 3
unit_price = 12.50
print(quantity)

Le langage Python autorise le point-virgule pour séparer plusieurs instructions sur une même ligne, mais cette écriture est généralement évitée pour préserver la lisibilité.

Attention : dans cet exemple, la valeur 12.50 crée une variable de type float, type qui correspond à un nombre à virgule flottante et ne constitue pas l'équivalent du type decimal de C#. Pour des calculs nécessitant une représentation décimale, Python propose le type Decimal dans le module decimal.

L'indentation et les blocs de code

En C#, les accolades délimitent les blocs de code. En Python, ce rôle est assuré par l'indentation.

En C# :

if (quantity > 0)
{
    Console.WriteLine("La quantité est positive.");
    Console.WriteLine("La commande peut être créée.");
}

Console.WriteLine("Fin du traitement.");

En Python :

if quantity > 0:
    print("La quantité est positive.")
    print("La commande peut être créée.")

print("Fin du traitement.")

Les deux instructions indentées appartiennent au bloc conditionnel if. La dernière instruction retrouve le niveau d'indentation précédent et se situe donc en dehors de ce bloc.

Le caractère : introduit le bloc après la condition. Il est également utilisé après les déclarations de fonctions, les boucles et d'autres constructions du langage.

La convention habituelle consiste à utiliser quatre espaces par niveau d'indentation. Il est conseillé d'éviter de mélanger les espaces et les tabulations.

Les commentaires

Les commentaires sur une ligne commencent par le caractère #.

# Calculer le montant total
total = quantity * unit_price

print(total)  # Afficher le résultat

Python ne possède pas de syntaxe de commentaire de bloc directement équivalente à /* ... */ en C#. Pour commenter plusieurs lignes, on peut placer le caractère # au début de chacune.

# Vérifier la quantité.
# Calculer le montant total.
# Afficher le résultat.

Les chaînes délimitées par trois guillemets sont parfois utilisées comme des commentaires, mais elles restent des chaînes de caractères. Elles servent notamment à écrire des chaînes multilignes et des chaînes de documentation, appelées docstrings.

Les variables et le typage dynamique

Une variable est créée lorsqu'une valeur lui est affectée.

quantity = 3
customer_name = "Alice"
is_valid = True

Il n'est pas nécessaire de préciser son type dans cette écriture. Cela ne signifie pas que le langage Python ne possède pas de types. Ici :

  • 3 est de type int ;
  • "Alice" est de type str ;
  • True est de type bool.

En Python, les variables sont des noms associés à des objets. Chaque objet possède un type, mais un même nom peut être associé successivement à des objets de types différents.

value = 42
value = "Bonjour"

Cette écriture est autorisée. Elle n'est toutefois pas toujours souhaitable : réutiliser une variable pour des données de nature différente peut rendre le code plus difficile à comprendre.

En C#, une variable déclarée avec l'inférence de type var conserve un type déterminé à la compilation :

var value = 42;

// Erreur de compilation : value est de type int.
value = "Bonjour";

Ainsi, le typage dynamique de Python ne correspond pas à l'inférence de type réalisée par var en C#.

La fonction type() permet d'obtenir le type d'un objet :

quantity = 3

print(type(quantity))  # <class 'int'>

Enfin, Python ne réalise pas toutes les conversions implicites entre les types. Par exemple, l'expression suivante provoque une erreur :

message = "Quantité : " + 3

Il faut convertir explicitement le nombre en chaîne de caractères ou utiliser une chaîne formatée :

message = "Quantité : " + str(3)

Les annotations de type

Python permet d'ajouter des annotations de type aux variables et aux fonctions.

quantity: int = 3
customer_name: str = "Alice"

Ces annotations documentent les types attendus et peuvent être exploitées par l'éditeur ou par un outil d'analyse de code statique. Elles ne rendent cependant pas le langage Python plus "fortement typé" et ne permettent pas de déclencher une vérification des types à l'exécution. Pour un développeur C#, les annotations peuvent constituer des repères utiles, mais leur rôle doit être distingué de celui des déclarations de type en C#.

quantity: int = 3

# Autorisé à l'exécution.
# Un outil d'analyse statique peut signaler l'incompatibilité.
quantity = "trois"

Les conventions de nommage

Python est sensible à la casse en distinguant les caractères majuscules des caractères minuscules. Par exemple, dans ce bloc de code, ces deux noms correspondent à deux variables différentes :

quantity = 3
Quantity = 5

Les conventions de nommage habituellement utilisées diffèrent également de celles du langage C# :

Élément Convention Python Exemple
Variable snake_case customer_name
Fonction snake_case calculate_total
Classe PascalCase CustomerOrder
Constante Majuscules avec séparateurs MAX_RETRY_COUNT

Le nommage en majuscules indique qu'une valeur doit être considérée comme une constante. Il n'empêche toutefois pas sa réaffectation : Python ne possède pas de mot-clé équivalent à const pour ce cas.

Les valeurs booléennes et l'absence de valeur

Les valeurs booléennes s'écrivent True et False, avec la première lettre en majuscule.

is_valid = True
is_cancelled = False

L'absence de valeur est généralement représentée par None.

customer = None

Pour vérifier qu'une variable contient None, nous utilisons l'opérateur is :

if customer is None:
    print("Aucun client n'a été sélectionné.")

La vérification complémentaire utilise is not :

if customer is not None:
    print("Un client a été sélectionné.")

None est l'équivalent de null dans de nombreux cas en C#, mais il s'agit d'un objet particulier du langage Python.

Les opérateurs

Plusieurs opérateurs sont familiers aux développeurs C# :

total = quantity * unit_price
quantity = quantity + 1
quantity += 1

is_equal = quantity == 3
is_different = quantity != 3

D'autres présentent des différences :

Opération C# Python
ET logique && and
OU logique \|\| or
Négation logique ! not
Puissance Math.Pow(a, b) a ** b
Division entière pour deux entiers positifs a / b a // b

Par exemple :

if quantity > 0 and not is_cancelled:
    print("La commande peut être traitée.")

En Python, l'opérateur / réalise une division dont le résultat est un nombre à virgule flottante pour deux opérandes entiers :

print(7 / 2)   # 3.5
print(7 // 2)  # 3
print(7 % 2)   # 1
print(2 ** 3)  # 8

Attention aux nombres négatifs : l'opérateur // arrondit le quotient vers l'entier inférieur :

print(-7 // 2)  # -4

En C#, la division entière donne -3 pour -7 / 2. Python ne possède pas d'opérateurs ++ et --. On utilise += 1 et -= 1.

L'égalité et l'identité

L'opérateur == compare l'égalité selon le comportement défini par les types concernés. L'opérateur is vérifie si les deux expressions désignent le même objet.

first = [1, 2, 3]
second = [1, 2, 3]

print(first == second)  # True : même contenu
print(first is second)  # False : objets distincts

Pour ces listes, l'opérateur == compare les éléments qu'elles contiennent. Il ne faut donc pas transposer systématiquement le comportement des opérateurs de C# à Python.

L'opérateur is ne doit pas être utilisé pour comparer des nombres ou le contenu de chaînes. Son utilisation la plus courante dans du code de base est la comparaison avec None.

Les chaînes de caractères

Les chaînes peuvent être délimitées par des apostrophes ou des guillemets.

first_name = 'Alice'
last_name = "Martin"

Contrairement à C#, les apostrophes ne servent pas à déclarer un caractère. Python ne possède pas de type char séparé : une chaîne d'un seul caractère reste de type str.

letter = "A"

Les f-strings permettent d'insérer des expressions dans une chaîne. Elles jouent un rôle comparable aux chaînes interpolées de C#.

En C# :

string message = $"La quantité est de {quantity}.";

En Python :

message = f"La quantité est de {quantity}."

Il est également possible de préciser un format :

total = 37.5

print(f"Montant : {total:.2f} €")

Cette instruction affiche :

Montant : 37.50 €

Les triples guillemets permettent d'écrire une chaîne sur plusieurs lignes :

message = """Bonjour,
Votre commande a été enregistrée.
Merci pour votre confiance."""

Les structures conditionnelles

Une structure conditionnelle utilise les mots-clés if, elif et else :

if quantity < 0:
    print("La quantité est invalide.")
elif quantity == 0:
    print("La commande est vide.")
else:
    print("La commande contient des articles.")

elif correspond à else if en C#. Les parenthèses autour de la condition ne sont pas nécessaires.

Python accepte également les expressions conditionnelles :

status = "Disponible" if quantity > 0 else "Indisponible"

En C#, l'équivalent est d'utiliser l'opérateur ternaire ? :

string status = quantity > 0 ? "Disponible" : "Indisponible";

Autre différence importante : une condition Python peut évaluer directement une valeur qui n'est pas de type bool.

customer_name = ""

if customer_name:
    print("Le nom est renseigné.")

Une chaîne vide est considérée "comme fausse". C'est également le cas de None, de zéro et des collections vides. Une chaîne non vide est considérée "comme vraie", même si elle contient le texte "False".

Les structures itératives

La structure itérative for parcourt les éléments d'un objet itérable. Son usage courant est donc proche de celui de foreach en C# :

names = ["Alice", "Bob", "Claire"]

for name in names:
    print(name)

Pour parcourir une séquence d'entiers, on peut utiliser la fonction range() :

for index in range(3):
    print(index)

Cette boucle affiche les valeurs 0, 1 et 2. La borne de fin est exclue.

for index in range(1, 4):
    print(index)

Cette seconde boucle affiche les valeurs 1, 2 et 3.

La structure itérative while répète un traitement tant qu'une condition est vraie :

remaining_attempts = 3

while remaining_attempts > 0:
    print(remaining_attempts)
    remaining_attempts -= 1

Comme en C#, break interrompt le traitement itératif et continue passe à l'itération suivante.

Les fonctions

Une fonction est déclarée avec le mot-clé def.

def calculate_total(quantity, unit_price):
    return quantity * unit_price

Son appel utilise une syntaxe familière :

total = calculate_total(3, 12.50)
print(total)

Les paramètres et la valeur de retour peuvent être annotés :

def calculate_total(quantity: int, unit_price: float) -> float:
    return quantity * unit_price

Les fonctions peuvent être définies au niveau d'un module, sans être placées dans une classe. Une fonction qui se termine sans retourner explicitement de valeur retourne None.

def display_message(message: str) -> None:
    print(message)

Les principales collections

Python propose une syntaxe directe pour créer plusieurs types de collections.

# Liste : collection modifiable
names = ["Alice", "Bob", "Claire"]

# Tuple : collection dont les éléments ne peuvent pas être remplacés
coordinates = (10, 20)

# Dictionnaire : associations entre clés et valeurs
customer = {
    "name": "Alice",
    "city": "Nantes",
}

# Ensemble : éléments uniques, sans ordre garanti
roles = {"reader", "editor"}

L'accès à un élément d'une liste ou d'un dictionnaire utilise les crochets :

print(names[0])
print(customer["name"])

Les indices commencent à zéro. Un indice négatif permet de compter depuis la fin d'une séquence :

print(names[-1])  # Claire

La fonction len() retourne le nombre d'éléments :

print(len(names))  # 3

Enfin, l'opérateur in permet de vérifier une appartenance :

if "Alice" in names:
    print("Alice figure dans la liste.")

Les instructions réparties sur plusieurs lignes

Pour plus de lisibilité, une instruction peut être répartie sur plusieurs lignes à l'intérieur de parenthèses, de crochets ou d'accolades.

total = (
    quantity * unit_price
    + shipping_cost
    - discount
)

Cela s'applique aussi aux appels de fonctions :

total = calculate_total(
    quantity=3,
    unit_price=12.50,
)

Les arguments sont transmis en précisant le nom des paramètres.

Les blocs provisoirement vides

Un bloc Python doit contenir au moins une instruction. L'utilisation du mot-clé pass permet de laisser temporairement un bloc sans traitement.

def process_order():
    pass

pass ne réalise aucune opération. Il est utile pour préparer la structure du programme avant d'implémenter le traitement.

Bloc de code récapitulatif

Voici un bloc de code récapitulatif du contenu de ce chapitre. Dans les chapitres suivants, nous aborderons l'utilisation des classes, de la gestion des erreurs et des imports.

Cet exemple récapitule les principales notions présentées dans ce chapitre : indentation, variables, annotations de type, fonctions, conditions, listes, boucles et chaînes interpolées. Le mot-clé raise permet ici de lever une exception, comme le mot-clé throw en C#.

def calculate_total(quantity: int, unit_price: float) -> float:
    if quantity < 0:
        raise ValueError("La quantité ne peut pas être négative.")

    return quantity * unit_price


quantities = [2, 0, 5]
unit_price = 12.50

for quantity in quantities:
    if quantity == 0:
        continue

    total = calculate_total(quantity, unit_price)
    print(f"Quantité : {quantity}, montant : {total:.2f} €")