Python Language
Exceptions du Commonwealth
Recherche…
Introduction
Ici, dans Stack Overflow, nous voyons souvent des doublons parlant des mêmes erreurs: "ImportError: No module named '??????'
, SyntaxError: invalid syntax
ou NameError: name '???' is not defined
c'est un effort pour les réduire et avoir des documents à relier.
IndentationErrors (ou indentation SyntaxErrors)
Dans la plupart des autres langages, l'indentation n'est pas obligatoire, mais en Python (et autres langages: premières versions de FORTRAN, Makefiles, Whitespace (langage ésotérique), etc.), ce qui peut être déroutant si vous venez d'une autre langue. Si vous copiez du code d'un exemple vers le vôtre ou simplement si vous êtes nouveau.
IndentationError / SyntaxError: retrait inattendu
Cette exception est levée lorsque le niveau d'indentation augmente sans raison.
Exemple
Il n'y a aucune raison d'augmenter le niveau ici:
print "This line is ok"
print "This line isn't ok"
print("This line is ok")
print("This line isn't ok")
Ici, il y a deux erreurs: la dernière et que l'indentation ne correspond à aucun niveau d'indentation. Cependant, un seul est affiché:
print "This line is ok"
print "This line isn't ok"
print("This line is ok")
print("This line isn't ok")
IndentationError / SyntaxError: unindent ne correspond à aucun niveau d'indentation externe
Apparaît que vous ne vous êtes pas complètement désintéressé.
Exemple
def foo():
print "This should be part of foo()"
print "ERROR!"
print "This is not a part of foo()"
print("This line is ok")
print("This line isn't ok")
IndentationError: attend un bloc en retrait
Après deux points (puis une nouvelle ligne), le niveau d'indentation doit augmenter. Cette erreur est soulevée lorsque cela ne s'est pas produit.
Exemple
if ok:
doStuff()
Remarque : Utilisez le mot pass
clé pass
(qui ne fait absolument rien) pour mettre simplement une method
if
, else
, except
, class
, method
ou definition
sans indiquer ce qui se passera si appelé / condition est vrai (mais le faire plus tard ou dans le cas de except
: il suffit de ne rien faire):
def foo():
pass
IndentationError: utilisation incohérente des tabulations et des espaces dans l'indentation
Exemple
def foo():
if ok:
return "Two != Four != Tab"
return "i dont care i do whatever i want"
Comment éviter cette erreur
N'utilisez pas d'onglets. Il est déconseillé par PEP8
, le guide de style pour Python.
- Configurez votre éditeur pour utiliser 4 espaces pour l'indentation.
- Effectuez une recherche et remplacez pour remplacer tous les onglets par 4 espaces.
- Assurez-vous que votre éditeur est configuré pour afficher des onglets de 8 espaces, afin que vous puissiez facilement réaliser cette erreur et la corriger.
Voir cette question si vous voulez en savoir plus.
TypeErrors
Ces exceptions sont provoquées lorsque le type d'un objet doit être différent
TypeError: [définition / méthode] prend? arguments positionnels mais? a été donné
Une fonction ou une méthode a été appelée avec plus (ou moins) d’arguments que ceux qu’elle peut accepter.
Exemple
Si plus d'arguments sont donnés:
def foo(a): return a
foo(a,b,c,d) #And a,b,c,d are defined
Si moins d'arguments sont donnés:
def foo(a,b,c,d): return a += b + c + d
foo(a) #And a is defined
Note : si vous voulez utiliser un nombre inconnu d’arguments, vous pouvez utiliser *args
ou **kwargs
. Voir * args et ** kwargs
TypeError: type (s) d'opérande non pris en charge pour [opérande]: '???' et '???'
Certains types ne peuvent pas être utilisés ensemble, selon l'opérande.
Exemple
Par exemple: +
est utilisé pour concaténer et ajouter, mais vous ne pouvez en utiliser aucun pour les deux types. Par exemple, essayer de créer un set
en concaténant ( +
ing) 'set1'
et 'tuple1'
donne l'erreur. Code:
set1, tuple1 = {1,2}, (3,4)
a = set1 + tuple1
Certains types (ex: int
et string
) utilisent à la fois +
mais pour des choses différentes:
b = 400 + 'foo'
Ou ils ne peuvent même pas être utilisés pour rien:
c = ["a","b"] - [1,2]
Mais vous pouvez par exemple ajouter un float
à un int
:
d = 1 + 1.0
Erreur-type: '???' l'objet n'est pas itérable / inscriptible:
Pour qu'un objet puisse être itéré, il peut prendre des index séquentiels à partir de zéro jusqu'à ce que les index ne soient plus valides et qu'un IndexError
soit généré (plus techniquement: il doit avoir une méthode __iter__
qui retourne un __iterator__
ou qui définit une méthode __getitem__
ce qui a été mentionné précédemment).
Exemple
Ici, nous disons que la bar
est le point zéro de 1. Nonsense:
foo = 1
bar = foo[0]
Ceci est une version plus discrète: Dans cet exemple for
tente de mettre x
à amount[0]
, le premier élément dans un itérables mais il ne peut pas parce que le montant est un entier:
amount = 10
for x in amount: print(x)
Erreur-type: '???' l'objet n'est pas appelable
Vous définissez une variable et l'appelez plus tard (comme ce que vous faites avec une fonction ou une méthode)
Exemple
foo = "notAFunction"
foo()
NameError: name '???' n'est pas défini
Est déclenché lorsque vous avez essayé d'utiliser une variable, une méthode ou une fonction qui n'est pas initialisée (du moins pas avant). En d'autres termes, il est déclenché lorsqu'un nom local ou global demandé n'est pas trouvé. Il est possible que vous ayez mal saisi le nom de l'objet ou que vous ayez oublié d' import
quelque chose. Aussi peut-être que c'est dans un autre domaine. Nous couvrirons ceux avec des exemples séparés.
Ce n'est tout simplement pas défini nulle part dans le code
Il est possible que vous ayez oublié de l'initialiser, surtout s'il s'agit d'une constante
foo # This variable is not defined
bar() # This function is not defined
Peut-être que c'est défini plus tard:
baz()
def baz():
pass
Ou il n'a pas été import
ed:
#needs import math
def sqrt():
x = float(input("Value: "))
return math.sqrt(x)
Les portées Python et la règle LEGB:
La règle dite LEGB parle des portées Python. Son nom est basé sur les différentes portées, classées selon les priorités correspondantes:
Local → Enclosed → Global → Built-in.
- L ocal: Variables non déclarées globales ou assignées dans une fonction.
- E nclosing: Les variables définies dans une fonction qui est enveloppé dans une autre fonction.
- G lobal: Variables déclarées globales ou affectées au niveau supérieur d'un fichier.
- B uilt-in: Variables pré-affectées dans le module de noms intégré.
Par exemple:
for i in range(4):
d = i * 2
print(d)
d
est accessible car la boucle for
ne marque pas une nouvelle étendue, mais si c'était le cas, nous aurions une erreur et son comportement serait similaire à:
def noaccess():
for i in range(4):
d = i * 2
noaccess()
print(d)
Python dit NameError: name 'd' is not defined
Autres erreurs
AssertError
La assert
déclaration existe dans presque toutes les langues de programmation. Quand tu fais:
assert condition
ou:
assert condition, message
C'est équivalent à ceci:
if __debug__:
if not condition: raise AssertionError(message)
Les assertions peuvent inclure un message facultatif et vous pouvez les désactiver lorsque vous avez terminé le débogage.
Remarque : la variable intégrée debug est True dans des circonstances normales, False lorsque l'optimisation est demandée (option de ligne de commande -O). Les tâches à déboguer sont illégales. La valeur de la variable intégrée est déterminée au démarrage de l'interpréteur.
KeyboardInterrupt
Erreur lorsque l'utilisateur appuie sur la touche d'interruption, normalement Ctrl + C ou del .
ZeroDivisionError
Vous avez essayé de calculer 1/0
qui n'est pas défini. Voir cet exemple pour trouver les diviseurs d'un nombre:
div = float(raw_input("Divisors of: "))
for x in xrange(div+1): #includes the number itself and zero
if div/x == div//x:
print x, "is a divisor of", div
div = int(input("Divisors of: "))
for x in range(div+1): #includes the number itself and zero
if div/x == div//x:
print(x, "is a divisor of", div)
Il déclenche ZeroDivisionError
car la boucle for
assigne cette valeur à x
. Au lieu de cela, il devrait être:
div = float(raw_input("Divisors of: "))
for x in xrange(1,div+1): #includes the number itself but not zero
if div/x == div//x:
print x, "is a divisor of", div
div = int(input("Divisors of: "))
for x in range(1,div+1): #includes the number itself but not zero
if div/x == div//x:
print(x, "is a divisor of", div)
Erreur de syntaxe sur un bon code
La plupart du temps, une erreur de syntaxe qui pointe vers une ligne inintéressante signifie qu'il y a un problème sur la ligne avant (dans cet exemple, il manque une parenthèse):
def my_print():
x = (1 + 1
print(x)
Résultats
File "<input>", line 3
print(x)
^
SyntaxError: invalid syntax
La raison la plus courante de ce problème est que les parenthèses / crochets ne correspondent pas, comme le montre l'exemple.
Il y a une mise en garde majeure pour les instructions d'impression dans Python 3:
>>> print "hello world"
File "<stdin>", line 1
print "hello world"
^
SyntaxError: invalid syntax
Parce que l'instruction print
été remplacée par la fonction print()
, vous souhaitez donc:
print("hello world") # Note this is valid for both Py2 & Py3