En exécutant le code suivant, quel est l'ordre des lignes affichées de haut en bas ?
def calc(a, b): try: print("try") r = a / b except ZeroDivisionError: print("except") else: print("else") finally: print("finally")calc(9, 3)
try, puis else, puis except
try, puis else, puis finally
try, puis except, puis else
try, puis except, puis finally
RéponseB. try, puis else, puis finally
9 / 3 ne lève pas d'exception, donc on n'entre pas dans except. La clause else n'étant exécutée que lorsqu'aucune exception ne s'est produite, elle s'exécute après le try. La clause finally s'exécute toujours en dernier, qu'il y ait eu ou non une exception. Le résultat est donc 3 lignes : try, else, finally. Les options faisant apparaître except correspondent à l'hypothèse erronée qu'une exception se serait produite, alors qu'aucune ZeroDivisionError ne survient dans cet appel. L'option où finally manque correspond à l'erreur de considérer finally comme « le nettoyage exécuté seulement en cas d'exception ».
Q2 | La clause else
Quelle est la condition correcte d'exécution de la clause else d'une instruction try ?
Elle s'exécute toujours en dernier, qu'une exception se soit produite ou non
Elle ne s'exécute que si une exception s'est produite dans la clause try
Elle s'exécute lorsqu'aucune clause except ne correspond
Elle ne s'exécute que si aucune exception ne s'est produite dans la clause try
RéponseD. Elle ne s'exécute que si aucune exception ne s'est produite dans la clause try
La clause else d'une instruction try ne s'exécute que si la clause try s'est terminée jusqu'au bout sans lever d'exception. Alors que le else d'une instruction if correspond au cas où « la condition est fausse », le else d'une instruction try correspond au cas où « tout s'est bien passé » ; il est utile de retenir que le sens est inversé. Ce qui s'exécute lorsqu'une exception survient est la clause except. Ce qui s'exécute toujours, qu'il y ait exception ou non, est la clause finally. Lorsqu'aucune clause except ne correspond, on ne tombe pas dans else : l'exception se propage vers l'appelant.
Q3 | Priorité de finally
Quel est le résultat de l'exécution du code suivant ?
f() prépare la valeur à retourner, puis exécute la clause finally avant de réellement la renvoyer. F s'affiche donc en premier, et la valeur de retour reste T. g() possède un return à l'intérieur de sa clause finally, qui écrase le return de la clause try, donnant une valeur de retour N. print évaluant f() et g() avant de tout afficher sur une même ligne, la ligne de F vient en premier, suivie de la ligne T N. L'option donnant T T correspondrait à croire que le return de finally est ignoré, et celle plaçant F en second correspondrait à croire que finally s'exécute après le return.
Q4 | Exception non capturable
Quelle exception ne peut pas être capturée par une clause except écrite comme except Exception ?
FileNotFoundError
ZeroDivisionError
KeyboardInterrupt
ModuleNotFoundError
RéponseC. KeyboardInterrupt
KeyboardInterrupt se trouve directement sous BaseException et n'hérite pas de Exception. issubclass(KeyboardInterrupt, Exception) vaut False. Comme elle correspond au cas où l'utilisateur tente d'arrêter le programme avec Ctrl-C, la hiérarchie est séparée pour éviter qu'un except Exception écrit de manière large ne l'absorbe par inadvertance. SystemExit se trouve au même niveau. Les trois autres sont tous des descendants de Exception : ZeroDivisionError se trouve sous ArithmeticError, FileNotFoundError sous OSError, et ModuleNotFoundError sous ImportError, si bien qu'ils peuvent tous être capturés par except Exception.
Q5 | Parent commun des exceptions
Quelle est la classe parente commune la plus proche de IndexError et KeyError ?
ReferenceError
ArithmeticError
AttributeError
LookupError
RéponseD. LookupError
IndexError comme KeyError partagent la même nature : une recherche par indice ou par clé n'a rien trouvé ; ils sont donc placés sous un parent commun, LookupError. En écrivant except LookupError, on peut recevoir à la fois un accès hors limites sur une liste et une clé absente d'un dictionnaire. ArithmeticError est le parent de ZeroDivisionError et d'autres, pour les cas où le calcul lui-même ne peut pas aboutir. AttributeError survient lorsqu'un attribut est introuvable, et ReferenceError lorsque la cible d'une référence faible a disparu ; les deux se trouvent directement sous Exception, dans une lignée distincte de LookupError.
Q6 | Ordre des except
Quel est le résultat correct de l'exécution du code suivant ?
try: x = 8 / 0except ArithmeticError: print("A")except ZeroDivisionError: print("Z")
Rien ne s'affiche, et l'exécution s'arrête
Seul Z s'affiche
A et Z s'affichent tous les deux
Seul A s'affiche
RéponseD. Seul A s'affiche
8 / 0 lève une ZeroDivisionError, qui est une sous-classe de ArithmeticError. Les clauses except sont examinées dans l'ordre, de haut en bas, et l'examen s'arrête à la première correspondance ; le except ArithmeticError écrit en premier capte donc l'exception, et seul A s'affiche. Le except ZeroDivisionError qui suit n'a jamais l'occasion de s'exécuter. Un seul except correspondant s'exécutant, on ne peut pas obtenir à la fois A et Z. Le principe est de placer le plus spécifique (sous-classe) en premier et le plus général (classe parente) ensuite ; le code de cette question a inversé cet ordre.
Q7 | Plusieurs exceptions
Quelle est la ligne unique affichée en exécutant le code suivant ?
En écrivant un tuple entre parenthèses après except, la clause s'exécute si l'une quelconque des exceptions du tuple correspond. conv("21") renvoie 42, car int("21") vaut 21. conv("abc") peut être transmis comme chaîne mais ne peut pas être interprété comme un nombre, ce qui donne une ValueError. conv(None) n'est pas d'un type transmissible à int(), ce qui donne une TypeError. La distinction « type correct mais valeur inadaptée donne ValueError, type incorrect dès le départ donne TypeError » constitue directement l'ordre de la bonne réponse.
Q8 | Relève d'exception
Quel est le résultat du code suivant, utilisant une exception personnalisée et un raise sans argument ?
class LoadError(Exception): passdef load(): try: raise LoadError("bad") except LoadError: print("inner") raisetry: load()except Exception as e: print("outer", type(e).__name__)
Seul inner s'affiche, outer ne s'affiche pas
2 lignes : inner puis outer Exception
2 lignes : inner puis outer LoadError
inner s'affiche, puis l'exécution s'arrête sur LoadError
RéponseC. 2 lignes : inner puis outer LoadError
Écrire simplement raise sans argument dans un except relève à l'identique l'exception en cours de traitement vers l'appelant. Après avoir affiché inner, LoadError se propage donc hors de load(), et le except Exception extérieur la reçoit. LoadError héritant de Exception, elle peut être capturée par except Exception, et l'exécution ne s'arrête pas. type(e).__name__ renvoyant le nom de la classe de l'exception réellement levée, c'est LoadError qui s'affiche, et non le nom du type du côté qui l'a capturée, Exception. Le cas où seul inner s'affiche correspondrait à une exception absorbée sur place sans être relevée.
Q9 | Exception non capturée
Quel résultat obtient-on en exécutant le code suivant ?
2 s'affiche, puis l'exécution s'arrête sur KeyError
2 lignes s'affichent : 2 puis not found
2 lignes s'affichent : 2 puis KeyError
2 lignes s'affichent : 2 puis None
RéponseA. 2 s'affiche, puis l'exécution s'arrête sur KeyError
Le premier appel utilise l'indice 1 de la liste, donnant 2. Le second interroge une clé absente du dictionnaire, ce qui lève une KeyError, mais seul IndexError est écrit dans le except. IndexError et KeyError sont tous deux des enfants de LookupError, mais ne sont pas l'un parent de l'autre, si bien qu'un except IndexError ne peut pas capturer une KeyError. L'exception non capturée se propage vers l'appelant, et faute de destinataire, le programme s'arrête. Pour recevoir les deux, il faut écrire except LookupError, ou aligner les deux dans un tuple.
Q10 | assert
Quelle description de l'instruction assert est correcte ?
Si la condition est fausse, elle lève une AssertionError, et elle est désactivée avec python3 -O
Si la condition est fausse, elle lève une AssertionError, et elle s'exécute toujours même avec python3 -O
Si la condition est vraie, elle lève une AssertionError, et elle est désactivée avec python3 -O
Si la condition est fausse, elle lève une ValueError, et elle s'exécute toujours même avec python3 -O
RéponseA. Si la condition est fausse, elle lève une AssertionError, et elle est désactivée avec python3 -O
assert condition, message lève une AssertionError lorsque la condition est fausse. Si la condition est vraie, rien ne se passe. Un point important est que, lancé en mode optimisé comme avec python3 -O, l'instruction assert est entièrement supprimée, et aucune ligne n'est exécutée. Il ne faut donc jamais utiliser assert pour vérifier une saisie de l'utilisateur ; pour cet usage, il faut vérifier la condition avec if et lever explicitement raise ValueError(...). Il est utile de retenir que assert est un outil destiné, pendant le développement, à consigner des hypothèses internes.
Q11 | self
Que dit correctement la description du premier paramètre self d'une méthode ?
C'est un nom réservé pour référencer les attributs de la classe parente
C'est un argument auquel l'instance elle-même, celle qui a appelé la méthode, est automatiquement transmise
C'est un argument destiné à créer une instance et à la renvoyer à l'appelant
C'est un nom réservé auquel la classe elle-même est automatiquement transmise
RéponseB. C'est un argument auquel l'instance elle-même, celle qui a appelé la méthode, est automatiquement transmise
Écrire d.speak() revient, pour Python, à l'interpréter comme Dog.speak(d) : c'est l'instance elle-même, celle qui a appelé la méthode, qui se retrouve à la position du premier argument. L'orthographe self n'est qu'une convention, ce n'est pas un nom réservé par le langage. Seule la position — le premier argument reçoit l'instance elle-même — fait partie de la spécification, donc écrire soi-même Dog.speak(d) fonctionne de la même façon. Créer et renvoyer une instance relève de __new__ et du mécanisme d'appel de la classe ; __init__ ne fait qu'initialiser une instance déjà créée. Pour référencer la classe parente, on utilise super().
Q12 | Variable de classe
Quelle est la sortie du code suivant qui modifie une variable de classe ?
kind est une variable de classe définie directement sous class ; toutes les instances créées à partir de cette classe partagent une seule et même valeur. Ni a ni b n'ont kind dans leur propre __dict__, donc en lisant l'attribut on remonte jusqu'à la classe et on voit la même valeur. L'affectation à Dog.kind modifie cette valeur partagée unique, si bien que a et b, déjà créés, affichent tous les deux wolf. La valeur n'est pas copiée au moment de la création de l'instance, donc l'option où canine subsiste n'est pas la bonne.
Q13 | Ombre d'attribut
Quelle est la sortie du code suivant, qui effectue une affectation côté instance ?
L'affectation a.kind ne modifie pas la variable de classe : elle crée une nouvelle entrée kind dans le dictionnaire d'instance de a. Par la suite, lire a.kind trouve d'abord cette nouvelle entrée, qui fait ainsi de l'ombre à la variable de classe. b et Dog.kind restent à canine. Le __dict__ de a contient donc, en plus de name posé dans __init__, également kind ; trié, cela donne ['kind', 'name']. L'option où tout devient husky correspond à l'idée erronée qu'une affectation sur l'instance modifierait la variable de classe ; celle qui ne garde que ['name'] correspond à l'idée qu'aucune ombre ne se crée.
Q14 | Partagée
Quelle est la sortie du code suivant qui fait d'une liste une variable de classe ?
self.items.append(x) n'est pas une affectation à self.items : c'est simplement un appel sur l'objet atteint via self.items. Ni p ni q n'ont leur propre items, donc les deux atteignent la même et unique liste, celle de la variable de classe. Le 1 ajouté via p et le 2 ajouté via q finissent donc dans la même liste, et les deux affichent [1, 2]. Pour que chaque instance ait son propre conteneur, il faut affecter self.items = [] dans __init__ ; on obtient alors [1] et [2] séparément.
Q15 | super()
Quelle est la sortie du code suivant qui utilise l'héritage et super() ?
Le __init__ de Cat appelle super().__init__(name), ce qui fait que le parent Animal se charge de définir self.name. Ensuite self.color reçoit black, donc les deux attributs sont présents. cry est redéfinie dans la classe fille, ce qui écrase l'implémentation du parent : c'est donc meow qui est appelée. isinstance(c, Animal) vaut True puisque Cat hérite d'Animal. Oublier d'appeler super() empêcherait de définir name et provoquerait une AttributeError — pas un échec silencieux comme le suggère l'option avec None.
Q16 | MRO
Quelle est la sortie du code suivant utilisant l'héritage multiple ?
class A: def who(self): return "A"class B(A): def who(self): return "B"class C(A): def who(self): return "C"class D(B, C): passprint(D().who())print([k.__name__ for k in D.__mro__])
B et ['D', 'B', 'C', 'A', 'object']
C et ['D', 'C', 'B', 'A', 'object']
B et ['D', 'B', 'A', 'C', 'object']
A et ['D', 'B', 'C', 'A', 'object']
RéponseA. B et ['D', 'B', 'C', 'A', 'object']
L'ordre de résolution des méthodes est déterminé par une règle appelée linéarisation C3, qui n'est pas un simple parcours en profondeur. Le parent commun A est placé après tous les enfants qui en héritent, ce qui donne l'ordre D, B, C, A, object. Un parcours en profondeur naïf qui descendrait dans B puis irait directement à A donnerait D, B, A, C, object — ce n'est pas le cas ici, et c'est le point à surveiller. who() cherche depuis le début du MRO et utilise la première méthode trouvée, donc c'est celle de B qui est retournée. Écrire class E(C, B) donnerait E, C, B, A, object : ce qui est écrit en premier a la priorité.
Q17 | Conflit de MRO
Si class B(A) est déjà définie, que se passe-t-il en écrivant class F(A, B): pass ?
La définition réussit, et F().who() appelle celle de A
La définition réussit, et __mro__ vaut F, A, B, object
La définition réussit, et F().who() appelle celle de B
Une TypeError se produit dès la définition de la classe
RéponseD. Une TypeError se produit dès la définition de la classe
La linéarisation C3 impose deux règles : respecter l'ordre dans lequel les classes de base sont listées, et placer un parent après ses enfants. F(A, B) demande que A soit placé avant B, mais B hérite de A, donc le parent A doit venir après son enfant B. Ces deux exigences ne peuvent être satisfaites simultanément : comme aucun MRO cohérent n'est possible, une TypeError se produit dès que la définition de la classe est évaluée. Ce n'est pas au moment de l'exécution qu'on le découvre : l'échec survient dès que l'instruction class est traitée. La forme correcte est class F(B, A), en plaçant l'enfant en premier.
Q18 | Modification de nom
Quelle est la sortie du code suivant, qui a des attributs commençant par un tiret bas ?
Un tiret bas simple en début de nom, comme _one, n'indique un usage interne que par convention : le nom n'est pas modifié et reste lisible normalement de l'extérieur. Deux tirets bas en début de nom, comme __two, déclenchent une modification de nom (name mangling) : le nom réel de l'attribut devient _P__two, soit _NomDeClasse__nom. C'est pourquoi écrire p.__two lève une AttributeError, alors que p._P__two fonctionne. C'est aussi le nom modifié qui apparaît dans __dict__, donc trié cela donne ['_P__two', '_one']. Seuls les noms à deux tirets bas sont concernés ; _one n'est pas modifié.
Q19 | Méthodes spéciales
Quelle est la sortie du code suivant, qui définit des méthodes spéciales ?
print(v) et str(v) utilisent __str__, d'où V(1, 2). En revanche, à l'intérieur d'un conteneur comme une liste ou un dictionnaire, c'est __repr__ qui est utilisé pour chaque élément, d'où [Vec(x=1, y=2)] à l'affichage. Cette distinction est le cœur de la question. len(v) renvoie ce que retourne __len__, soit 2 ; v + Vec(3, 4) renvoie ce que retourne __add__, un nouveau Vec, et le passer à print utilise de nouveau __str__, d'où l'affichage V(4, 6). Une classe sans __str__ utilise __repr__ à sa place, mais l'inverse — __str__ utilisé à la place de __repr__ — ne se produit jamais.
Q20 | __eq__
Quelle est la sortie du code suivant, qui définit uniquement __eq__ ?
class Point: def __init__(self, x): self.x = x def __eq__(self, other): return self.x == other.xp = Point(1)q = Point(1)print(p == q, p is q)print(Point.__hash__ is None)try: print(len({p, q}))except TypeError: print("TypeError")
True False et False et 2
True False et True et TypeError
True False et False et 1
True True et True et TypeError
RéponseB. True False et True et TypeError
Comme __eq__ est défini, p == q compare l'attribut x et vaut True, mais p et q restent deux objets créés séparément, donc p is q reste False. Le point important ici est qu'une classe qui définit __eq__ voit son __hash__ automatiquement mis à None : Point.__hash__ is None vaut True. Un objet sans hash ne peut pas servir de clé de dictionnaire ni entrer dans un ensemble, donc tenter de créer {p, q} lève une TypeError. Pour pouvoir aussi les mettre dans un ensemble, il faut définir soi-même un __hash__ qui renvoie la même valeur pour des objets égaux.
Q21 | math
Quelle est la sortie du code suivant, qui utilise le module math ?
math.sqrt renvoie toujours un float, même quand la division tombe juste, donc la racine carrée de 16 s'affiche 4.0 et non 4. math.floor arrondit vers le bas sur la droite numérique, donc -1.5 devient -2 ; math.ceil arrondit vers le haut, donc -1.5 devient -1. Pour les nombres négatifs, il faut noter que int(-1.5), qui tronque vers zéro, donne -1, ce qui diffère du résultat de floor. Confondre floor et ceil donne l'ordre -1 -2 ; croire que sqrt renvoie un int donne 4.
Q22 | os.path
Quelle est la combinaison de valeurs renvoyées par os.path.splitext('/tmp/z.txt') et os.path.basename('/tmp/z.txt') ?
('/tmp/z', '.txt') et 'z.txt'
('/tmp', 'z.txt') et '/tmp'
('/tmp/z', 'txt') et 'z.txt'
('/tmp/z.txt', '') et 'z.txt'
RéponseA. ('/tmp/z', '.txt') et 'z.txt'
os.path.splitext sépare uniquement l'extension et renvoie un tuple à deux éléments, en gardant le point du côté de l'extension : le résultat est donc ('/tmp/z', '.txt'). Le point ne disparaît jamais pour donner 'txt'. os.path.basename renvoie le nom situé à la fin du chemin, soit 'z.txt'. C'est os.path.dirname qui renvoie la partie répertoire, '/tmp' ; pour obtenir les deux à la fois sous forme de tuple, on utilise os.path.split. Il faut bien distinguer que splitext coupe sur l'extension, pas sur un séparateur de répertoire.
Q23 | Correspondance avec re
Quelle est la sortie du code suivant qui utilise le module re ?
re.match ne fait correspondre qu'à partir du début de la chaîne ; le début de 'abc' est 'a', donc il ne correspond pas à 'b' et renvoie None. re.search cherche aussi plus loin dans la chaîne, donc il correspond à 'b', et .group() récupère la chaîne trouvée, b. Cette différence est le point le plus souvent testé sur re. re.findall renvoie une liste de toutes les portions correspondant au motif ; \d+ désigne une suite de chiffres consécutifs, donc le résultat est ['1', '22', '333']. Les caractères séparateurs ne sont jamais inclus. En l'absence de correspondance, une liste vide est renvoyée.
Q24 | datetime
Quelle est la sortie du code suivant qui utilise datetime ?
Afficher directement un objet date le fait au format ISO, séparé par des tirets, donc 2026-08-22. Pour changer le format, on utilise strftime : passer '%Y/%m/%d' renvoie la chaîne 2026/08/22, séparée par des barres obliques. Ajouter un timedelta(days=10) à une date renvoie non pas un timedelta mais une nouvelle date pointant dix jours plus tard ; affichée, elle donne 2026-09-01. Le calcul à travers le changement de mois est pris en charge par datetime, donc il n'en résulte jamais une date inexistante comme 2026-08-32, qui viendrait d'un simple ajout de 10 au chiffre du jour. On pourrait croire que print(d) suit le même format que strftime, ce qui donnerait des barres obliques, mais l'affichage par défaut utilise des tirets. Soustraire deux dates renvoie non pas une date mais un timedelta, dont l'affichage prend une forme comme 10 days, 0:00:00.
Q25 | Counter
Quelle est la sortie du code suivant qui utilise collections.Counter ?
from collections import Counterc = Counter("abracadabra")print(c.most_common(2))print(c["a"], c["z"])
[('a', 5), ('b', 2)] et 5 et KeyError
[('a', 5), ('r', 2)] et 5 0
[('a', 5), ('b', 2)] et 5 0
[('a', 5), ('b', 2), ('r', 2)] et 5 0
RéponseC. [('a', 5), ('b', 2)] et 5 0
Dans 'abracadabra', a apparaît 5 fois, b et r apparaissent chacun 2 fois, c et d une fois chacun. most_common(2) renvoie seulement les 2 éléments les plus fréquents, sous forme d'une liste de tuples (élément, effectif), donc [('a', 5), ('b', 2)]. Entre b et r, à égalité, c'est celui apparu en premier qui passe avant, donc b est retenu. Counter est une sorte de dictionnaire, mais interroger un élément absent ne lève pas de KeyError et renvoie 0 : c'est ce qui le distingue d'un dictionnaire ordinaire, conçu pour éviter d'avoir à vérifier l'existence avant de compter.
Q26 | namedtuple
Quelle est la sortie du code suivant qui utilise un type créé avec namedtuple ?
Un type créé par namedtuple s'affiche sous une forme portant le nom du type et les noms des champs, soit Pt(x=1, y=2). Les valeurs sont accessibles aussi bien par nom que par indice, donc p.x et p[0] valent tous les deux 1. Et comme namedtuple est un sous-type de tuple, isinstance(p, tuple) vaut True. Autrement dit, c'est une variété de tuple, et ses éléments ne peuvent pas être modifiés après coup. Pour obtenir des valeurs modifiables, on utilise _replace, qui crée une nouvelle instance avec la valeur remplacée, ou bien on définit une classe ordinaire.
Q27 | À usage unique
Quelle est la sortie du code suivant qui passe deux fois le même objet map à list() ?
m = map(str, [1, 2, 3])print(list(m))print(list(m))
1re ligne : ['1', '2', '3'], 2e ligne : None
1re ligne : ['1', '2', '3'], 2e ligne : []
1re ligne : [1, 2, 3], 2e ligne : []
1re et 2e ligne : ['1', '2', '3']
RéponseB. 1re ligne : ['1', '2', '3'], 2e ligne : []
map ne renvoie pas une liste mais un itérateur, qui livre une valeur à la fois à chaque next(), et n'en donne plus une fois épuisé. Le premier list() en extrait les trois valeurs, donc le second list() renvoie une liste vide car il ne reste plus rien. Il n'y a ni erreur ni None, juste un épuisement silencieux, ce qui rend le piège facile à manquer. map(str, ...) convertit chaque élément en chaîne, donc le contenu de la première extraction n'est pas des nombres mais ['1', '2', '3']. Le même phénomène se produit avec filter, zip, enumerate et les générateurs ; si l'on doit parcourir plusieurs fois, il faut figer le résultat avec list() dès la réception.
Q28 | filter, all et any
Quelle est la sortie du code suivant qui utilise filter, all et any ?
Passer None comme premier argument à filter revient à filtrer selon la véracité de l'élément lui-même. 0, la chaîne vide et None sont évalués comme faux et donc écartés ; il reste [1, 2, 'a']. Ce ne sont pas les éléments écartés qui sont conservés. all renvoie True dès lors qu'aucun élément n'est faux, ce qui inclut le cas d'une liste vide sans aucun élément, donc True. any renvoie True s'il existe au moins un élément vrai, donc False pour une liste vide. Le fait que ces deux fonctions donnent des réponses opposées sur une séquence vide est un point souvent testé.
Q29 | Générateur
Dans le code suivant contenant yield, dans quel ordre les lignes s'affichent-elles à l'appel de la fonction ?
Appeler une fonction contenant yield n'exécute aucune ligne de son corps : seul un objet générateur est renvoyé, donc created s'affiche en premier. C'est seulement au premier next(g) que l'exécution démarre réellement depuis le début, affiche start, puis s'arrête sur yield 1 en renvoyant 1. Le next(g) suivant reprend là où l'exécution s'était arrêtée, affiche mid, puis s'arrête sur yield 2 en renvoyant 2. Cette exécution différée est la différence décisive avec une fonction ordinaire ; un next(g) supplémentaire ferait se terminer la fonction et lèverait StopIteration.
Q30 | is et ==
Quelle est la sortie du code suivant qui met côte à côte les opérateurs is et == ?
a = [1, 2]b = [1, 2]c = aprint(a == b, a is b)print(a == c, a is c)
True False et True False
True True et True True
False False et True True
True False et True True
RéponseD. True False et True True
== est l'opérateur qui demande si les valeurs sont égales, donc pour a et b, dont le contenu est identique, il vaut True. is demande si c'est le même objet ; a et b sont deux listes créées séparément, donc False. En revanche, c = a ne crée pas de nouvelle liste, mais donne simplement un autre nom au même objet, donc a is c vaut True. Autrement dit, modifier la liste via c rend le changement visible aussi depuis a. None est un objet spécial unique en son genre, ce qui explique la convention d'écrire x is None ; mais pour comparer des valeurs, on utilise toujours ==.
Entraînement : répondez aux questions de cette page
Cet outil d'entraînement pose les questions dans un ordre aléatoire (il fonctionne lorsque JavaScript est activé). Vous pouvez de toute façon lire toutes les questions et explications ci-dessus.
* Les explications sont fournies à titre d'information pour l'étude. Le programme et le système des examens changent selon les années : vérifiez toujours les annonces officielles de l'organisme qui organise l'examen.
Cette page est une traduction du texte original japonais. En cas de différence entre la traduction et l'original, la version japonaise fait foi. Voir l'original en japonais