Mémo Python3 - Introduction et B-A-BA

image Monty Python

Comme Gustave Thibon refusant d'écrire son dernier livre au prétexte que tout a déjà été écrit, je ne souhaite pas ici ré-écrire un autre tutoriel sur Python. Je me contenterai comme à mon habitude de retenir les bases et quelques subtilités sans trop d'explications histoire de faire travailler ses neurones et combler quelques trous de mémoire.

Installation et version

Trêve de bavardage. La plupart des distributions Linux disposent d'une version de python installée, la question est de savoir la quelle. Ouvrez une console et tapez ...

$ python3 --version
Python 3.10.6

On peut être surpris de ne pas écrire simplement $ python. C'est en fait une question de compatibilité avec les versions antérieure à python3.

À ce jour la dernière version de python est 3.11 mais mon système ne me la propose pas par défaut mais rien ne vous empêche de l'installer.

# apt install python3.11

Celle-ci ne viendra pas remplacer la version installée sur votre ordinateur mais il est possible de changer de version par défaut ou d'appeler une version explicitement comme expliqué ci-après.

Python en console

Pour être tout à fait exacte on n'utilise pas python en console, on demande à la console d’exécuter l'interpréteur python, c'est le mode interactif et ça se passe ainsi:

$ python3 
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

Ou si vous préférez une autre version que celle installée par défaut

$ python3.11
Python 3.11.0rc1 (main, Aug 12 2022, 10:02:14) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

Les trois chevrons >>> attendent que vous écriviez quelques instructions en python.

>>> 3*(5+2)
21
>>>

Bon je ne m'attarde pas plus sur le mode interactif qui est un outil instantané très pratique pour des tests ou des calcules à la volée, il est tout à fait capable de se souvenir des variables et autres fonctions que vous lui déclarerez ... tant qu'il reste ouvert. Une fois l'interpréteur fermé (quit() ou CTRL+D) il oubliera tout ce que vous lui avez apprit.

Python en script

On nomme généralement les fichiers de script python avec le suffixe .py. Il s'agit plus d'une convention que d'une nécessité pour que nous, humains, puissions les reconnaître d'un seul coup d’œil. Le système lui n'a pas besoin de ce détail pour savoir à qui il a affaire, le système lit l'entête du fichier; le shebang.

Le shebang:

Sur une distribution Linux il est indispensable d'indiquer un shebang en entête de fichier.py, tous vos scripts python devraient commencer par quelque chose comme ça:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

La première ligne indique à l'interpréteur quelle version de python utiliser, c'est le shebang à proprement parler. Si comme ici on ne précise pas le suffixe de version (3.xx) c'est la version par défaut du système qui sera utilisée. Si vous souhaiter utiliser une version en particulier il suffira d'indiquer le chemin où elle se trouve, comme ceci: #!/usr/bin/python3.11.

Si vous ne savez pas où est installé python un petit $ whereis python3.11 peut aider

La seconde ligne demande à utiliser exclusivement l'encodage de caractères en utf-8. Cette dernière est facultative mais nous assurera, à nous francophones, que nos caractères accentués s'afficheront correctement.

Pour que python puisse interpréter un fichier.py ce dernier doit être configuré avec les droits à l’exécution : $ chmod +x fichier.py.

Nous n'avons plus qu'à appeler le script depuis un terminal.

$ ./script.py

Je vous ai dit ci-dessus que sur "Linux il est indispensable d'indiquer un shebang", en fait j'ai menti. Vous pouvez tout à fait appeler un fichier sans sheebang comme ça $ python3 script.py mais c'est plus long et rien dans votre code n'indique quelle version utiliser.

Commentaires et documentations

# commentaire simple

""" commentaire
sur plusieurs
lignes """

Au delà du commentaire, les trois guillemets permettent de documenter les fonctions les classes et les modules et de rendre cette documentation accessible par le biais de la fonction native help().

def fonk():
    """" Cette fonction fait ceci cela """
    pass

help(fonk)

retournera en console

Help on function fonk in module __main__:

fonk()
    " Cette fonction fait ceci cela
(END)

Les opérateurs arithmétiques

nombres (tuto python.org)

En python l'incrémentation (var++) et la décrémentation (var--) n'existent pas.

Les variables

Déclarer des variables

On déclare une variable de la manière la plus simple:

nbr = 5
txt = "un peu de texte"

Il est possible de déclarer plusieurs variables d'un seul coup:

size = w, h = 500, 300
print(size)
(500, 300)
print(w)
500
print(h)
300

Les types de variable

Identifier une variable

Identifier une variable pour connaitre son type:

var = 1.5
print(type(var))
<class 'float'>

Comparer une variable pour vérifier son type

var = 1.5
print(isinstance(var,int))
False
print(isinstance(var,float))
True

Portée des variables

portée et espaces de noms (tuto python.org)

Une variable a une portée locale au bloc dans le quel elle a été déclarée

nbr = 3
def f1():
    nbr += 2
    print(nbr)
f1()
UnboundLocalError: local variable 'nbr' referenced before assignment

Le mot clé "global" permet de rendre une variable accessible dans l'ensemble du script.

nbr = 3
def f1():
    global nbr
    nbr += 2
    print(nbr)
f1()
5

À noter qu'il existe également le mot clé "nonlocal" qui s'utilise avec des fonctions imbriquées. Sa portée va jusqu'à la fonction englobante parente

def f1():
    nbr = 3
    def f2():
        nonlocal nbr
        nbr += 2
    f2()
    print(nbr)
f1()
 5

Le caractère souligné (_)

En mode interactif uniquement il est possible de récupérer le retour de la dernière instruction grâce au caractère souligné (_).

>>> a = 1.618
>>> b = 6922.47
>>> a*b
11200.556460000002
>>> 10+_
11210.556460000002

Cette variable doit être considérée comme une variable en lecture seule par l'utilisateur. Ne lui affectez pas de valeur explicitement — vous créeriez ainsi une variable locale indépendante, avec le même nom, qui masquerait la variable native et son fonctionnement magique.

Les chaînes de caractères

chaînes de caractères (tuto python.org)
formatage (tuto python.org)

Il est possible de combiner variables et chaînes de caractères sans passer par la concaténation grâce au caractère f (ou F) avant l'ouverture des guillemets:

var1 = "maison"
var2 = "mites"
var3 = "femmes"
print(f"Ma {var1} est envahie par des {var2}")

Boucles et conditions

Parenthèse sur les blocs d'instruction

Là ou d'autres langages utilisent les accolades, en python c'est l'indentation qui délimite les blocs d'instruction.

Généralement une indentation est constituée soit d'une tabulation soit de plusieurs espaces (2,4 ou 8 c'est selon). En python la convention demande d'utiliser 4 espaces. Paramétrez votre éditeur pour qu'il se comporte ainsi (Avec Sublime Text c'est tout en bas à droite).

Si vous avez mélangé tabulation et espaces dans votre code vous aurez le message explicite:

TabError: inconsistent use of tabs and spaces in indentation

+ sur les conditions (tuto python.org)

Les opérateurs de comparaison

Les opérateurs logiques

(tuto python.org) plus d'informations

if elif else

Une simple condition if elif else

age = 50
if age < 18:
    print("vous êtes mineur")
elif age >= 18 and age <= 65:
    print("vous êtes majeur")
else :
    print("Vous êtes vieux")

Une condition if else en écriture simplifiée

majeur = "oui" if age >= 18 else "non"
print("Êtes vous majeur?", majeur)

for

for + range(), break, continue (tuto python.org)

Une simple boucle for ...

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

... affichera dans un terminal

0
1
2

On boucle sur une liste très simplement

lst = ["abc", "def", "ghi"]
for value in lst:
    print(value)

Si on a besoin de l'indice on utilisera "enumerate()"

lst = ["abc", "def", "ghi"]
for index, value in enumerate(lst):
    print(index, value)

while

Une simple boucle while ...

n = 0
while n < 3:
    print(n)
    n += 1

... affichera dans un terminal

0
1
2

match

match (tuto python.org)

reponse = "a"

match reponse:
    case "a" : 
        print(1)
    case "b" : 
        print(2)
    case "c" :
        print(3)

Les boucles et la clause else

Avec une boucle for ...

for n in range(3,0,-1):
    print(n)
else:
    print("zero")

... ou avec une boucle while ...

n = 3
while n > 0:
    print(n)
    n-=1
else:
    print("zero")

... les deux afficheront dans un terminal:

3
2
1
zero

Les structures de données

Les listes

listes (tuto python.org)
compléments (tuto python.org)

On peut apparenter les listes (list) en Python aux tableaux (array) dans d'autres langages de programmation.

On peut déclarer une liste de différentes manières.

liste = [] # une liste vide
liste = ["a","b","c"]
liste = list(range(1,10)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Accéder à un élément par son index:

liste[1]

Supprimer le dernier élément, la liste est modifiée

liste.pop()

listes en compréhension

Une listes en compréhension est une liste créée à partir d'une liste initiale sur laquelle on applique un filtre. Ici nous allons extraire les nombres pairs de la liste initiale et les multiplier par 2.

initiale = [1,2,3,4,5,6,7,8,9]
comp = [i*2 for i in liste_initiale if i%2 == 0]

Comprenez comp = [opération itération condition] où la condition est optionnelle.

Les tuples

n-uplets (tuto python.org)

Les ensembles

sets (tuto python.org)

les dictionnaires

dictionnaires (tuto python.org)

On peut déclarer un dictionnaire de deux manières:

notes = {"Pierre":15, "Paul":11, "Jacques":17}

ou avec le constructeur dict() si les clés sont des chaînes de caractères

notes = dict(Pierre=15, Paul=11, Jacques=17)

Ajouter une entrée:

notes["Juda"] = 2

Supprimer une entrée:

del notes['juda']

Lister les clés:

list(notes)

Trier les clés par ordre numérico-alphabétique croissant:

sorted(notes)

Plus difficile, trier par valeur décroissante:

notes = dict(sorted(notes.items(), key=lambda i: i[1], reverse=True))

Les dictionnaires en compréhension

Comme pour les listes il est possible de produire des dictionnaires en compréhension:

fibo = (1,1,2,3,5,8,13)
fibocarre = {x: x**2 for x in fibo}

produira:

{1: 1, 2: 4, 3: 9, 5: 25, 8: 64, 13: 169}

N'oubliez pas qu'un index doit impérativement être unique ce qui explique que la sortie produite ait omis (ou plutôt écrasée) le premier "1" du n-uplet "fibo".

Méthode pour extraire les n premières entrées d'un dictionnaire

dico = {"a":2, "b":4,"c":8,"d":16,"e":32}
for i, (k, v) in zip(range(3), dico.items()):
    print(k,v)

Les fonctions

Fonctions natives (doc python.org)

Définition d'une fonction à 1 argument

def cube(n):
    return n**3

fonctions (tuto python.org)

*args **kwargs arguments arbitraires

Un astérisque (*) devant un nom d'argument permet à la fonction de recevoir un nombre arbitraire d'arguments dans un tuple.

def f(*args):
    print(type(args))
    for i in args:
        print(i)

f(1, 2, 3)

Retournera en console:

<class 'tuple'>
1
2
3

Deux astérisques (**) devant un nom d'argument permet à la fonction de recevoir un nombre arbitraire d'arguments nommés dans un dictionnaire.

def f(**kwargs):
    print(type(kwargs))
    for i in kwargs:
        print(i, kwargs[i])

f(a=1, b=2, c=3)

retournera en console

<class 'dict'>
a 1
b 2
c 3

Les modules

Tout script python est un module, celui que l'on appel en premier dans la console (ex: ./script.py) est le module __main__. On peut donc appeler de script en script, d'autres scripts qu'on appellera des modules.

(tuto python.org) modules
(tuto python.org) survole des bibliothèques natives
(doc python.org) index des modules natifs

B-A-BA des modules

Supposons le module "testModule.py"

var = 1234

def f1():
    return "je suis une fonction"

Maintenant dans un fichier quelconque on charge le module et on s'en sert:

import testModule

print(testModule.f1(), testModule.var)

Dans ces exemples on suppose que le fichier appelant et le fichier du module sont au même niveau, si le module est dans un sous répertoire on l’appellera ainsi import dossier.module

On peut aussi, le temps de son utilisation, changer le nom de la variable d'accès au module:

import testModule as mod

print(mod.f1(), mod.var)

On peut aussi s'épargner de réécrire le nom du module, attention toute fois aux espaces de noms:

from testModule import *

print(f1(), var)

Il est également possible de n'importer que certains éléments:

from testModule import f1, var

print(f1(), var)

Dans tous les cas présentés le résultat en console sera le même:

je suis une fonction 1234

if __name__ == "__main__"

Comme je l'ai mentionné au début de ce chapitre le premier fichier que vous appelez dans la console pour démarrer votre application est le __main__, en fait il prend le nom de __main__ et donc en toute logique si le nom d'un fichier est __main__ alors c'est que c'est lui qui à été appelé en premier. Il est donc possible d’exécuter du code seulement si un fichier à été appeler directement ce qui peut être très pratique pour tester les modules ou les classes que vous êtes en train d'écrire.

Si je reprends l'exemple du module "testModule.py" on pourrait avoir ceci:

def f1():
    return "je suis une fonction"

if __name__ == "__main__":

    def f2(x):
        print(x)

    f2(f1())

Enfin depuis une console je n'ai plus qu'à appeler mon $ ./testModule.py pour que le code s’exécute.

Depuis l'interpréteur python c'est l'interpréteur qui prend le nom __main__

dir() Y'a quoi dans ce module

La fonction "dir()" liste tous les types de noms : les variables, fonctions, modules, etc. Utilisée avec l'exemple ci-dessus ça donne ça:

import testModule
print(dir(testModule))

en console on obtient:

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'f1', 'var']

Obtenir la liste des modules installés

Depuis l'interpréteur python

help('modules')

Dans le cas d'un environnement virtuel il est préférable d'utiliser pip depuis une console

$ python3 -m pip list

Connaitre l'emplacement d'un module:

>>> import os
>>> print(os.__file__)
/usr/lib/python3.8/os.py

À qui est cette fonction

Même si ce n'est pas recommandé, il peut arriver que l'on importe tout (*) de plusieurs modules du coup on ne sait plus très bien de quel module est appelée telle fonction/méthode

from toto import *
from titi import *
import inspect

a = fonctionBidule() 

# de quel module est appelée la fonctionBidule()?

reponse = inspect.getmodule(fonctionBidule())

print(reponse)

Lire et écrire des fichiers

Lecture et écriture de fichiers python.org

Ouverture d'un fichier

Que ce soit pour lire ou écrire dans un fichier on commence toujours par appeler la fonction open(). Elle prend au moins un arguments, le chemin vers le fichier à ouvrir, mais on l'utilise généralement avec un second argument; le mode d'ouverture.

data = open("fichier.txt", "r")

Les différents modes d'ouverture de fichier en python sont semblables à ceux utilisés dans d'autres langages de programmation.

Notez que les modes r et t sont les deux modes par défaut ce qui signifie que
open("fichier.txt") , open("fichier.txt", "r") et open("fichier.txt", "rt")
sont parfaitement identiques, de même que open("fichier.txt", "r+") se comportera exactement de la même manière que open("fichier.txt", "w").

Lire dans un fichier

f = open("fichier.txt", "r")
data = f.read()

Rien de compliqué ici, on ouvre le fichier en mode lecture (r) et on récupère son contenu (en mode texte par défaut) dans la variable "data".

Écrire dans un fichier

f = open("fichier.txt", "a")
f.write("Ceci")
f.write(" cela")

Cette fois ci on ouvre le fichier en mode ajout (a), le texte "Ceci cela" s'écrira dans le fichier sur la même ligne. Si l'on souhaite aller à la ligne suivante on ajoutera simplement un saute de ligne grâce à la combinaison "\n" soit directement dans le corps du texte (f.write("Ceci\ncela")) soit explicitement (f.write("\n")) chaque fois que nécessaire.

Fermeture d'un fichier

Jusqu'à présent nous avons ouvert des fichiers sans les refermer et ça c'est mal, surtout que c'est comme le réfrigérateur c'est pas bien compliqué, il faut juste le faire. Donc une fois qu'on à fini de travailler avec un fichier il faut le fermer.

f = open("fichier.txt")
data = f.read()
f.close()

Cependant le mot clé "with" permet de ne pas avoir à se soucier de ce détail.

with open("fichier.txt") as f:
    data = f.read()

Le format JSON

Json python.org

Avant tout on importe le module json

import json

Supposons des données quelconques:

data = {"nom": "Jeanne", "prenom":"Calment", "dates":{"nais":(21,2,1875), "mort":(4,8,1997)}}

Ouverture ou création d'un fichier .json

with open("chemin/vers/fichier.json", "wt") as params:
    json.dump(data, params)

Récupérer des données dans un fichier .json

with open("chemin/vers/fichier.json", "rt") as params:
    data = json.load(params)

J'ai mis ci dessus le minimum à écrire mais dans la pratique on préférera plutôt écrire les choses ainsi:

import json

def json_put(file, data):
    try:
        with open(file, "wt") as params:
            json.dump(data, params)
    except:
        print("Erreur: Impossible d'écrire dans le fichier.")

def json_get(file):
    try:
        with open(file, "rt") as params:
            return json.load(params)
    except:
        print(f"Erreur: Le fichier {file} n'existe pas.")

Les classes

classes première approche (tuto python.org)

Définition

Définition d'une classe simple à deux attributs; une variable (n) et une méthode (calcule()).

class Cube:

    n = 12
    def calcule(self):
        return self.n ** 3

On notera seulement deux choses, conventionnellement le nom de la classe commence par une majuscule et le mot clé self qui fait référence à l'objet de la classe.

La méthode __init__() : le constructeur

La vocation du constructeur est d'initialiser les attributs lors de l'instanciation de la classe.

class Puissance:

    def __init__(self, libre, carre=2, cube=3)
        self.libre = libre
        self.carre = carre
        self.cube = cube

Variables de classe et variables d’instance

Une variable de classe est commune à toutes les instances (objets) créées alors qu'une variable d'instance sera propre à chaque objet (instance de la classe). On les utilisera donc en connaissance de cause.

class Puissance:

    carre = 2 # variable de classe
    cube = 3  # variable de classe

    def __init__(self, autre=0):
        self.autre = autre # variable d'instance


if __name__ == "__main__":

    p1 = Puissance(4)
    p2 = Puissance(8)
    print(p1.carre, p2.carre)
    print(p1.cube, p2.cube)
    print(p1.autre, p2.autre)

Affichera en console

2 2
3 3
4 8

 Héritage

Héritage simple:

class Maman():
    def __init__(self):
        self.nom = "Dubois"
        self.prenom = "Cecile"

class Fille(Maman):
    def __init__(self):
        super().__init__()
        self.prenom = "Eloise"

fille = Fille()
print(fille.nom, fille.prenom)
Dubois Eloise

Héritage multiple

class Lucy():
    def __init__(self):
        self.nom = "Lucy"

class Meme():
    def __init__(self):
        self.nom = "Meme"

class Maman():
    def __init__(self):
        self.nom = "Maman"


class Fille(Lucy, Meme, Maman):
    def __init__(self):
        super().__init__()

fille = Fille()
print(fille.nom)
Lucy

Variables privées et surcharge

Déclarer une variable en la préfixant d'un tiret bas (_var) indique au développeur que cette variable ne devrait pas être appelée depuis l'extérieur de la classe mais ne change en rien le comportement de python qui agira avec elle comme avec n'importe quelle variable. En fait c'est une convention.

Par contre, préfixer une variable de deux tirets bas (__var) (et au plus un tiret bas à la fin) permet à python de préfixer la variable par le nom de la classe et ainsi inclure la variable dans l'espace de nom de la classe. Démonstration:

class Maman:
    def __init__(self):
        self.fonk1()
        self.__fonk2()

    def fonk1(self):
        print("Maman 1")

    def fonk2(self):
        print("Maman 2")

    __fonk2 = fonk2   # copie privée de fonk2()

class Fille(Maman):

    def fonk1(self):
        print("Fille 1")

    def fonk2(self):
        print("Fille 2")

f = Fille()
f.fonk1()
f.fonk2()
Fille 1
Maman 2
Fille 1
Fille 2

Pip et environnements virtuels (venv)

On pourrait se demander pourquoi utiliser Pip pour installer des modules Python alors qu'il est tout à fait possible de les installer avec "apt" comme n'importe quel autre paquet Linux. Pour ma part je pense que c'est étroitement lié aux environnements virtuels qui permettent d'isoler vos différents projets et de les protéger de versions différentes de Python et des modules utilisés.

 Pip

Documentation officiel pip

Pip est un module python et devrait donc déjà être installé, pour le vérifier on peut essayer ça.

$ python3 -m pip --version
pip 23.1.2 from /home/user/.local/lib/python3.10/site-packages/pip (python 3.10)

Sur les distributions basées sur Debian (c'est le cas de Ubuntu) il est nécessaire d'installer pip par les dépôts: # apt install python3-pip

Si la version n'est pas à jour:

$ python3 -m pip install --upgrade pip 

Installer un module:

$ python3 -m pip install <nom_module>

Désinstaller un module:

$ python3 -m pip uninstall <nom_module>

Obtenir la liste des modules installés avec pip:

$ python3 -m pip list

venv

venv (doc python.org)

Pour faire simple et rapide, un environnement virtuel est un répertoire que vous créez là où bon vous semble qui contiendra une copie des binaires, exécutables, modules, librairies, etc... dont vous allez vous servir pour créer votre application, ceci afin de garder un contrôle au cas par cas des différentes versions utilisés dans vos projets.

Créer un environnement virtuel est une opération plutôt simple.

$ python3 -m venv /chemin/vers/environnent/virtuel/

Oups,

The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt install python3.10-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment.

heureusement comme souvent avec Linux le message est clair: installer le paquet python3.10-venv et recommencer. À adapter à votre version de python bien sûr.

Ici j'ai laissé la version de python par défaut de mon système mais on peut demander à installer une version en particulier et c'est justement pour cela qu'on le fait.

$ python3.11 -m venv /chemin/vers/environnent/virtuel/

Activer l'environnement:

$ source /chemin/vers/environnent/virtuel/bin/activate

J'ai mis ici un chemin absolu mais il va de sois que l'on peut faire plus simple si la commande est passée depuis le répertoire du projet $ source bin/activate on peut encore faire plus simple comme ça: $ . bin/activate.

Et pour le désactiver:

$ deactivate

Compléments divers

 Liens utiles

 Pyinstaller

site officiel Pyinstalleur

Pyinstaller est un module python qui permet de compiler les applications python en paquets, binaires, exécutables afin des les distribuer et permettre aux utilisateurs de les installer facilement.

pyinstaller -F -w -i=app.ico app.py

Passer des arguments à un script (sys.argv)

Un fichier.py

import sys

if len(sys.argv) > 1:
    print(f"il y a {len(sys.argv)-1} argument(s)")
else:
    print("pas d'argument")

print(sys.argv)

L'appel de ce fichier dans une console avec les arguments a b c retournera

$ ./fichier.py a b c
il y a 3 argument(s)
['./fichier.py', 'a', 'b', 'c']

Si vous l'avez remarqué sys.argv retourne une liste et les listes sont indexées. Cette seconde approche est donc identique à la première, peut-être même plus élégante.

import sys

if len(sys.argv[1:]) > 0:
    print(f"il y a {len(sys.argv[1:])} argument(s)")
else:
    print("pas d'argument")

print(sys.argv)

Créer une variable à partir d'une chaîne grâce à eval()

action_avance = "hue"
action_arrete = "hoo"

def action(str):
    var = "action_"+str
    try:
        print(eval(var))
    except:
        print(var, "n'est pas une variable!")

action("avance")
action("arrete")
action("miaule")

Affichera en console:

hue
hoo
action_miaule n'est pas une variable!

print(r'chaîne brute')

Une chaîne brute (r pour raw) ne peut pas se terminer par un nombre impair de caractères \ (backslash)

>>> print(r'toto\tutu')
toto\tutu

>>> print(r'toto\tutu\')
  File "<stdin>", line 1
    print(r'toto\tutu\')
          ^
SyntaxError: unterminated string literal (detected at line 1)

>>> print(r'toto\tutu\\')
toto\tutu\\

informations et des solutions de contournement

os.path.isdir() ou isfile() retournent toujours True ou False

Supposons que le répertoire "test" contienne indifféremment des dossier et des fichier que nous souhaitons distinguer.

import os

# on se rends dans le répertoire test
os.chdir("test")

# on récupère le chemin dans la variable url
url = os.getcwd()

# on récupère le contenu dans la variable content 
content = os.listdir(url)

# on boucle sur chaque élément trouvé
for elem in content:
    if os.path.isfile(elem):
        print("FI: ",elem)
    else:
        print("FO: ",elem)

Ce code retournera "FO: ..." pour chaque occurrence trouvée quelle soit un fichier ou un dossier.

L'erreur courante consiste à tester directement l'élément trouvé sans utiliser le chemin absolu if os.path.isfile(elem). Ce code tente de vérifier si "elem" existe à la racine de l'ordinateur, n'existant probablement pas il retourne tout le temps "False".

On corrigera notre erreur en utilisant le chemin complet de l'élément:

# on boucle sur chaque élément trouvé
for elem in content:
    if os.path.isfile(os.path.join(url,elem)):
        print("FI: ",elem)
    else:
        print("FO: ",elem)
02-Apr-2024
^