Python Language
Commonwealth Uitzonderingen
Zoeken…
Invoering
Hier in Stack Overflow zien we vaak duplicaten die over dezelfde fouten praten: "ImportError: No module named '??????'
, SyntaxError: invalid syntax
of NameError: name '???' is not defined
. Dit is een poging om ze te verminderen en wat documentatie te hebben om naar te linken.
IndentationErrors (of inspringingssyntaxErrors)
In de meeste andere talen is inspringen niet verplicht, maar in Python (en andere talen: vroege versies van FORTRAN, Makefiles, Whitespace (esoterische taal), etc.) is dat niet het geval, wat verwarrend kan zijn als je uit een andere taal komt, als u code van een voorbeeld naar uw exemplaar kopieerde, of gewoon als u nieuw bent.
IndentationError / SyntaxError: onverwacht inspringen
Deze uitzondering wordt opgeworpen wanneer het inspringingsniveau zonder reden toeneemt.
Voorbeeld
Er is geen reden om het niveau hier te verhogen:
print "This line is ok"
print "This line isn't ok"
print("This line is ok")
print("This line isn't ok")
Hier zijn er twee fouten: de laatste en dat de inspringing niet overeenkomt met een inspringingsniveau. Er wordt echter maar één getoond:
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 komt niet overeen met een uiterlijk inspringingsniveau
Blijkt dat je niet volledig onhoorbaar bent.
Voorbeeld
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: verwacht een ingesprongen blok
Na een dubbele punt (en vervolgens een nieuwe regel) moet het inspringingsniveau toenemen. Deze fout wordt weergegeven wanneer dat niet is gebeurd.
Voorbeeld
if ok:
doStuff()
Opmerking : gebruik het sleutelwoord pass
(dat maakt absoluut niets) om gewoon een if
, else
, except
, class
, method
of definition
maar niet te zeggen wat er zal gebeuren als de naam / condition waar is (maar doe het later, of in het geval van except
: doe gewoon niets):
def foo():
pass
IndentationError: inconsistent gebruik van tabs en spaties bij inspringen
Voorbeeld
def foo():
if ok:
return "Two != Four != Tab"
return "i dont care i do whatever i want"
Hoe deze fout te voorkomen
Gebruik geen tabbladen. Het wordt afgeraden door PEP8
, de stijlgids voor Python.
- Stel uw editor in om 4 spaties te gebruiken voor inspringen.
- Zoek en vervang om alle tabbladen te vervangen door 4 spaties.
- Zorg ervoor dat uw redacteur is ingesteld op tabbladen voor het beeldscherm als 8 ruimtes, zodat u gemakkelijk kunt realiseren die fout repareren.
Bekijk deze vraag als je meer wilt weten.
TypeErrors
Deze uitzonderingen worden veroorzaakt wanneer het type van een object anders moet zijn
TypeError: [definition / method] neemt? positionele argumenten maar? is gegeven
Een functie of methode werd aangeroepen met meer (of minder) argumenten dan degene die het kan accepteren.
Voorbeeld
Als er meer argumenten worden gegeven:
def foo(a): return a
foo(a,b,c,d) #And a,b,c,d are defined
Als er minder argumenten worden gegeven:
def foo(a,b,c,d): return a += b + c + d
foo(a) #And a is defined
Opmerking : als u een onbekend aantal argumenten wilt gebruiken, kunt u *args
of **kwargs
. Zie * args en ** kwargs
TypeError: niet-ondersteunde operandtype (n) voor [operand]: '???' en '???'
Sommige typen kunnen niet samen worden gebruikt, afhankelijk van de operand.
Voorbeeld
Bijvoorbeeld: +
wordt gebruikt om samen te voegen en toe te voegen, maar u kunt geen van beide voor beide typen gebruiken. Als u bijvoorbeeld een set
probeert te maken door 'set1'
en 'tuple1'
( +
ing) 'tuple1'
geeft dit de foutmelding. Code:
set1, tuple1 = {1,2}, (3,4)
a = set1 + tuple1
Sommige typen (bijvoorbeeld: int
en string
) gebruiken beide +
maar voor verschillende dingen:
b = 400 + 'foo'
Of ze worden misschien nergens voor gebruikt:
c = ["a","b"] - [1,2]
Maar je kunt bijvoorbeeld een float
aan een int
:
d = 1 + 1.0
Typefout: '???' object is niet iterabel / subscriptabel:
Voor een itereerbaar object kan het opeenvolgende indexen nodig hebben beginnend vanaf nul totdat de indexen niet langer geldig zijn en een IndexError
wordt opgewekt (meer technisch: het moet een __iter__
methode hebben die een __iterator__
, of die een __getitem__
methode definieert die wel wat eerder werd genoemd).
Voorbeeld
Hier zeggen we dat bar
het nullenitem van 1 is. Onzin:
foo = 1
bar = foo[0]
Dit is een meer discrete versie: in dit voorbeeld for
pogingen om x
in te stellen op amount[0]
, het eerste item in een iterabel, maar dat kan niet omdat aantal een int is:
amount = 10
for x in amount: print(x)
Typefout: '???' object is niet opvraagbaar
U definieert een variabele en roept deze later aan (zoals wat u doet met een functie of methode)
Voorbeeld
foo = "notAFunction"
foo()
NameError: naam '???' is niet gedefinieerd
Wordt opgewekt wanneer u een variabele, methode of functie probeert te gebruiken die niet is geïnitialiseerd (althans niet eerder). Met andere woorden, deze wordt weergegeven wanneer een gevraagde lokale of globale naam niet wordt gevonden. Het is mogelijk dat u de naam van het object verkeerd gespeld hebt of bent vergeten iets te import
. Misschien is het ook in een ander bereik. We behandelen die met afzonderlijke voorbeelden.
Het is eenvoudigweg nergens in de code gedefinieerd
Het is mogelijk dat u bent vergeten het te initialiseren, vooral als het een constante is
foo # This variable is not defined
bar() # This function is not defined
Misschien is het later gedefinieerd:
baz()
def baz():
pass
Of het is niet import
:
#needs import math
def sqrt():
x = float(input("Value: "))
return math.sqrt(x)
Python-scopes en de LEGB-regel:
De zogenaamde LEGB-regel spreekt over de Python-scopes. De naam is gebaseerd op de verschillende bereiken, gerangschikt volgens de overeenkomstige prioriteiten:
Local → Enclosed → Global → Built-in.
- L ocal: variabelen die niet algemeen zijn opgegeven of in een functie zijn toegewezen.
- E nclosing: Variabelen gedefinieerd in een functie die is verpakt in een andere functie.
- G lobal: variabelen die algemeen zijn opgegeven of op het hoogste niveau van een bestand zijn toegewezen.
- B uilt-in: variabelen vooraf toegewezen in de ingebouwde namenmodule.
Als voorbeeld:
for i in range(4):
d = i * 2
print(d)
d
is toegankelijk omdat de for
lus geen nieuwe scope markeert, maar als dat wel zo is, hebben we een fout en zou het gedrag vergelijkbaar zijn met:
def noaccess():
for i in range(4):
d = i * 2
noaccess()
print(d)
Python zegt NameError: name 'd' is not defined
Overige fouten
AssertError
De assert
verklaring bestaat in bijna elke programmeertaal. Wanneer doe je:
assert condition
of:
assert condition, message
Het is hetzelfde als dit:
if __debug__:
if not condition: raise AssertionError(message)
Beweringen kunnen een optioneel bericht bevatten en u kunt ze uitschakelen als u klaar bent met foutopsporing.
Opmerking : de ingebouwde variabele debug is True onder normale omstandigheden, False wanneer optimalisatie wordt aangevraagd (opdrachtregeloptie -O). Toewijzingen voor foutopsporing zijn illegaal. De waarde voor de ingebouwde variabele wordt bepaald wanneer de tolk start.
KeyboardInterrupt
Fout opgetreden wanneer de gebruiker op de interrupt-toets drukt, normaal Ctrl + C of del .
ZeroDivisionError
U probeerde 1/0
te berekenen, wat niet is gedefinieerd. Zie dit voorbeeld om de delers van een getal te vinden:
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)
Het verhoogt ZeroDivisionError
omdat de for
lus die waarde toekent aan x
. In plaats daarvan zou het moeten zijn:
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)
Syntaxisfout op goede code
Het grootste deel van de tijd dat een SyntaxError die naar een oninteressante regel verwijst, betekent dat er een probleem is met de regel ervoor (in dit voorbeeld ontbreekt het tussen haakjes):
def my_print():
x = (1 + 1
print(x)
Geeft terug
File "<input>", line 3
print(x)
^
SyntaxError: invalid syntax
De meest voorkomende reden voor dit probleem is niet-overeenkomende haakjes / haakjes, zoals het voorbeeld laat zien.
Er is een belangrijk voorbehoud voor gedrukte uitspraken in Python 3:
>>> print "hello world"
File "<stdin>", line 1
print "hello world"
^
SyntaxError: invalid syntax
Omdat de print
is vervangen door de functie print()
, wilt u het volgende:
print("hello world") # Note this is valid for both Py2 & Py3