Python Language
Gemensamma undantag
Sök…
Introduktion
Här i Stack Overflow ser vi ofta duplikat som talar om samma fel: "ImportError: No module named '??????'
, SyntaxError: invalid syntax
eller NameError: name '???' is not defined
. Detta är ett försök att minska dem och ha viss dokumentation att länka till.
IndentationErrors (eller intryck SyntaxErrors)
På de flesta andra språk är intryck inte obligatoriskt, men i Python (och andra språk: tidiga versioner av FORTRAN, Makefiles, Whitespace (esoteriskt språk), etc.) så är inte fallet, vad kan vara förvirrande om du kommer från ett annat språk, om du kopierade kod från ett exempel till ditt eget, eller helt enkelt om du är ny.
IndentationError / SyntaxError: oväntat indrag
Detta undantag tas upp när indragningsnivån ökar utan anledning.
Exempel
Det finns ingen anledning att höja nivån här:
print "This line is ok"
print "This line isn't ok"
print("This line is ok")
print("This line isn't ok")
Här finns det två fel: det sista och att indragningen inte matchar någon indragningsnivå. Men bara en visas:
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 matchar inte någon yttre indragningsnivå
Visas att du inte avslappnade helt.
Exempel
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: förväntade ett intryckt block
Efter en kolon (och sedan en ny linje) måste indragningsnivån öka. Det här felet tas upp när det inte hände.
Exempel
if ok:
doStuff()
Obs: Använd sökordet pass
(som gör absolut ingenting) att bara sätta en if
, else
, except
, class
, method
eller definition
, men inte säga vad som kommer att hända om det är påkallat / villkoret är sant (men gör det senare, eller i fallet med except
: gör bara ingenting):
def foo():
pass
IndentationError: inkonsekvent användning av flikar och mellanslag i indragning
Exempel
def foo():
if ok:
return "Two != Four != Tab"
return "i dont care i do whatever i want"
Hur man undviker detta fel
Använd inte flikar. Det avskräcks av PEP8
, stilguiden för Python.
- Ställ in din redigerare för att använda fyra mellanslag för indragning.
- Gör en sökning och ersätt för att ersätta alla flikar med fyra mellanslag.
- Se till att din redigerare är inställd på att visa flikar som åtta mellanslag, så att du lätt kan inse det felet och fixa det.
Se den här frågan om du vill lära dig mer.
TypeErrors
Dessa undantag orsakas när typen av något objekt ska vara annorlunda
TypeError: [definition / metod] tar? positionella argument men? gavs
En funktion eller metod kallades med fler (eller mindre) argument än de som den kan acceptera.
Exempel
Om fler argument ges:
def foo(a): return a
foo(a,b,c,d) #And a,b,c,d are defined
Om mindre argument ges:
def foo(a,b,c,d): return a += b + c + d
foo(a) #And a is defined
Obs! Om du vill använda ett okänt antal argument kan du använda *args
eller **kwargs
. Se * args och ** kwargs
TypeError: operandtyp (er) för [operand] som inte stöds: '???' och '???'
Vissa typer kan inte användas tillsammans, beroende på operand.
Exempel
Till exempel: +
används för att sammanfoga och lägga till, men du kan inte använda någon av dem för båda typerna. Att försöka göra en set
genom att sammanfoga ( +
ing) 'set1'
och 'tuple1'
ger felet. Koda:
set1, tuple1 = {1,2}, (3,4)
a = set1 + tuple1
Vissa typer (t.ex.: int
och string
) använder båda +
men för olika saker:
b = 400 + 'foo'
Eller så kan de inte ens användas för något:
c = ["a","b"] - [1,2]
Men du kan till exempel lägga till en float
i ett int
:
d = 1 + 1.0
Skrivfel: '???' objektet är inte iterable / subscriptable:
För att ett objekt kan upprepas kan det ta sekventiella index som börjar från noll tills indexen inte längre är giltiga och en IndexError
höjs (mer tekniskt: det måste ha en __iter__
metod som returnerar en __iterator__
, eller som definierar en __getitem__
metod som gör vad som tidigare nämnts).
Exempel
Här säger vi att bar
är nollpunkten på 1. Nonsense:
foo = 1
bar = foo[0]
Detta är en mer diskret version: I det här exemplet for
försöka ställa in x
till amount[0]
, är det första objektet i en iterable men det kan inte eftersom beloppet är ett int:
amount = 10
for x in amount: print(x)
Skrivfel: '???' föremålet är inte kallbart
Du definierar en variabel och kallar den senare (som vad du gör med en funktion eller metod)
Exempel
foo = "notAFunction"
foo()
NameError: name '???' är inte definierad
Upphöjs när du försökte använda en variabel, metod eller funktion som inte är initialiserad (åtminstone inte förut). Med andra ord tas det upp när ett begärt lokalt eller globalt namn inte hittas. Det är möjligt att du har felstavat namnet på objektet eller glömt att import
något. Kanske är det inom ett annat område. Vi täcker de med separata exempel.
Det är helt enkelt inte definierat någonstans i koden
Det är möjligt att du har glömt att initiera det, speciellt om det är en konstant
foo # This variable is not defined
bar() # This function is not defined
Det kanske definieras senare:
baz()
def baz():
pass
Eller så import
det inte:
#needs import math
def sqrt():
x = float(input("Value: "))
return math.sqrt(x)
Python-omfattning och LEGB-regeln:
Den så kallade LEGB Rule talar om Python-räckvidden. Namnet är baserat på de olika räckvidden, beställd av korrespondentens prioriteringar:
Local → Enclosed → Global → Built-in.
- L ocal: Variabler som inte deklareras som globala eller tilldelade i en funktion.
- E nclosing: Variabler definierade i en funktion som är insvept i en annan funktion.
- G lobal: Variabler som deklareras globala eller tilldelas på toppnivån i en fil.
- B uilt-in: Variabler på förhand tilldelat i den inbyggda namn modul.
Som ett exempel:
for i in range(4):
d = i * 2
print(d)
d
är tillgängligt eftersom for
loopen inte markerar ett nytt omfång, men om det gjorde det skulle vi ha ett fel och dess beteende skulle likna:
def noaccess():
for i in range(4):
d = i * 2
noaccess()
print(d)
Python säger NameError: name 'd' is not defined
Andra fel
AssertError
Den assert
uttalande förekommer i nästan alla programmeringsspråk. När du gör:
assert condition
eller:
assert condition, message
Det motsvarar detta:
if __debug__:
if not condition: raise AssertionError(message)
Påståenden kan innehålla ett valfritt meddelande och du kan inaktivera dem när du är klar med felsökning.
Obs : den inbyggda variabla felsökningen är sant under normala omständigheter, falskt när optimering begärs (kommandoradalternativ -O). Uppdrag till felsökning är olagliga. Värdet för den inbyggda variabeln bestäms när tolkarna startar.
KeyboardInterrupt
Fel uppstod när användaren trycker på avbrytningsknappen, normalt Ctrl + C eller del .
ZeroDivisionError
Du försökte beräkna 1/0
vilket inte är definierat. Se detta exempel för att hitta delare av ett nummer:
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)
Det höjer ZeroDivisionError
eftersom for
slingan tilldelar detta värde till x
. Istället borde det vara:
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)
Syntaxfel vid bra kod
Den stora majoriteten av tiden en SyntaxError som pekar på en ointressant rad betyder att det finns ett problem på raden före den (i det här exemplet är det en saknad parentes):
def my_print():
x = (1 + 1
print(x)
Returer
File "<input>", line 3
print(x)
^
SyntaxError: invalid syntax
Det vanligaste skälet till detta problem är felinställda parenteser / parenteser, som exemplet visar.
Det finns en viktig varning för tryckta uttalanden i Python 3:
>>> print "hello world"
File "<stdin>", line 1
print "hello world"
^
SyntaxError: invalid syntax
Eftersom print
ersattes med print()
, så du vill:
print("hello world") # Note this is valid for both Py2 & Py3