Python Language
Исключения из Содружества
Поиск…
Вступление
Здесь, в Stack Overflow, мы часто видим дубликаты, говорящие о тех же ошибках: "ImportError: No module named '??????'
, SyntaxError: invalid syntax
или NameError: name '???' is not defined
. Это попытка уменьшить их и иметь ссылку на документацию.
ОтступыErrors (или отступы SyntaxErrors)
В большинстве других языков отступы не являются обязательными, но в Python (и на других языках: ранние версии FORTRAN, Makefiles, Whitespace (эзотерический язык) и т. Д.), Что не так, что может сбивать с толку, если вы пришли с другого языка, если вы копировали код из примера в свой собственный или просто, если вы новичок.
IndentationError / SyntaxError: неожиданный отступ
Это исключение возникает, когда уровень отступов увеличивается без причины.
пример
Нет причин для повышения уровня здесь:
print "This line is ok"
print "This line isn't ok"
print("This line is ok")
print("This line isn't ok")
Здесь есть две ошибки: последняя и что отступ не соответствует уровню отступов. Однако показано только одно:
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 не соответствует внешнему уровню отступа
Похоже, ты не отказался полностью.
пример
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: ожидается отложенный блок
После двоеточия (а затем новой строки) уровень отступов должен увеличиваться. Эта ошибка возникает, когда этого не происходит.
пример
if ok:
doStuff()
Примечание . Используйте ключевое слово pass
(что абсолютно ничего), чтобы просто положить if
, else
, except
, class
, method
или definition
но не сказать, что произойдет, если inv / condition истинно (но сделайте это позже или в случае except
: просто ничего не делать):
def foo():
pass
IndentationError: непоследовательное использование вкладок и пробелов в отступе
пример
def foo():
if ok:
return "Two != Four != Tab"
return "i dont care i do whatever i want"
Как избежать этой ошибки
Не используйте вкладки. Это обескураживает PEP8
, руководство по стилю для Python.
- Установите для вашего редактора четыре пробела для отступов.
- Сделайте поиск и замените, чтобы заменить все вкладки на 4 пробела.
- Убедитесь, что ваш редактор настроен на отображение вкладок в виде 8 пробелов, чтобы вы могли легко понять эту ошибку и исправить ее.
См. Этот вопрос, если вы хотите узнать больше.
TypeErrors
Эти исключения возникают, когда тип какого-либо объекта должен быть разным
ТипError: [определение / метод] занимает? позиционные аргументы, но? было дано
Функция или метод вызывались с более (или менее) аргументами, чем те, которые он может принять.
пример
Если даны дополнительные аргументы:
def foo(a): return a
foo(a,b,c,d) #And a,b,c,d are defined
Если даны меньше аргументов:
def foo(a,b,c,d): return a += b + c + d
foo(a) #And a is defined
Примечание . Если вы хотите использовать неизвестное количество аргументов, вы можете использовать *args
или **kwargs
. См. * Args и ** kwargs
TypeError: неподдерживаемый тип операндов для [операнда]: '???' а также '???'
Некоторые типы не могут работать вместе, в зависимости от операнда.
пример
Например: +
используется для конкатенации и добавления, но вы не можете использовать их для обоих типов. Например, попытка создания set
путем конкатенации ( +
ing) 'set1'
и 'tuple1'
дает ошибку. Код:
set1, tuple1 = {1,2}, (3,4)
a = set1 + tuple1
Некоторые типы (например: int
и string
) используют оба +
но для разных вещей:
b = 400 + 'foo'
Или они могут быть даже не использованы ни для чего:
c = ["a","b"] - [1,2]
Но вы можете, например, добавить float
в int
:
d = 1 + 1.0
TypeError: '???' объект не является итерируемым / индексируемым:
Для того, чтобы объект был итерируемым, он может принимать последовательные индексы, начиная с нуля, до тех пор, пока индексы перестанут быть действительными, а IndexError
будет поднят (более технически: он должен иметь метод __iter__
который возвращает __iterator__
или который определяет метод __getitem__
который делает что было упомянуто ранее).
пример
Здесь мы говорим, что bar
- это нулевой элемент 1. Чепуха:
foo = 1
bar = foo[0]
Это более дискретная версия: в этом примере for
попытки установить x
для amount[0]
первый элемент в итерируемой, но он не может, поскольку сумма является int:
amount = 10
for x in amount: print(x)
TypeError: '???' объект не может быть вызван
Вы определяете переменную и вызываете ее позже (например, что вы делаете с помощью функции или метода)
пример
foo = "notAFunction"
foo()
NameError: name '???' не определено
Повышается, когда вы пытались использовать переменную, метод или функцию, которая не инициализирована (по крайней мере, не раньше). Другими словами, он возникает, когда запрашиваемое локальное или глобальное имя не найдено. Возможно, вы пропустили имя объекта или забыли что-то import
. Также, возможно, это в другой сфере. Мы рассмотрим их отдельными примерами.
Это просто не определено нигде в коде
Возможно, вы забыли инициализировать его, особенно если он является постоянным
foo # This variable is not defined
bar() # This function is not defined
Возможно, это определено позже:
baz()
def baz():
pass
Или это не было import
:
#needs import math
def sqrt():
x = float(input("Value: "))
return math.sqrt(x)
Области Python и правило LEGB:
В так называемом правиле LEGB говорится о области Python. Это имя основано на разных областях, упорядоченных по соответствующим приоритетам:
Local → Enclosed → Global → Built-in.
- L ocal: Переменные, не объявленные глобальными или назначенные в функции.
- E nclosing: Переменные, определенные в функции, которая завернута в другую функцию.
- G lobal: переменные объявлены глобальными или назначаются на верхнем уровне файла.
- B uilt-in: Переменные, назначенные во встроенном модуле имен.
В качестве примера:
for i in range(4):
d = i * 2
print(d)
d
является доступным, потому что цикл for
не отмечает новую область видимости, но если бы это произошло, у нас была бы ошибка, и ее поведение было бы похоже на:
def noaccess():
for i in range(4):
d = i * 2
noaccess()
print(d)
Python говорит NameError: name 'd' is not defined
Другие ошибки
AssertError
Утверждение assert
существует почти на всех языках программирования. Когда вы выполните:
assert condition
или же:
assert condition, message
Это эквивалентно этому:
if __debug__:
if not condition: raise AssertionError(message)
Утверждения могут включать необязательное сообщение, и вы можете отключить их, когда вы закончите отладку.
Примечание : встроенная переменная debug True при нормальных обстоятельствах, False при запросе оптимизации (опция командной строки -O). Задания для отладки являются незаконными. Значение встроенной переменной определяется при запуске интерпретатора.
KeyboardInterrupt
Ошибка при нажатии на клавишу прерывания, обычно Ctrl + C или del .
ZeroDivisionError
Вы пытались вычислить 1/0
который не определен. См. Этот пример, чтобы найти делители числа:
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)
Он вызывает ZeroDivisionError
потому что цикл for
присваивает этому значению значение x
. Вместо этого это должно быть:
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)
Синтаксическая ошибка при хорошем коде
В большинстве случаев синтаксическая ошибка, указывающая на неинтересную строку, означает, что перед ней стоит проблема (в этом примере это недостающая скобка):
def my_print():
x = (1 + 1
print(x)
Возвращает
File "<input>", line 3
print(x)
^
SyntaxError: invalid syntax
Наиболее распространенная причина этой проблемы - несогласованные скобки / скобки, как показывает пример.
Существует одна серьезная оговорка для операторов печати в Python 3:
>>> print "hello world"
File "<stdin>", line 1
print "hello world"
^
SyntaxError: invalid syntax
Поскольку оператор print
был заменен функцией print()
, вы хотите:
print("hello world") # Note this is valid for both Py2 & Py3