Автор оригинала: Team Python Pool.
Ошибки – неотъемлемая часть жизни программиста. И это совсем не плохо, если вы получаете ошибку. Получение ошибки означает, что вы изучаете что-то новое. Но мы должны устранить эти ошибки. И прежде чем решить эту ошибку, мы должны знать, почему мы получаем эту ошибку. В python есть некоторые часто встречающиеся ошибки, такие как Ошибка типа , Синтаксическая ошибка, Ошибка ключа, Ошибка атрибута, Ошибка имени, и так далее.
В этой статье мы узнаем о том, что такое python AttributeError, почему мы его получаем и как его разрешаем? Интерпретатор Python вызывает AttributeError, когда мы пытаемся вызвать или получить доступ к атрибуту объекта, но этот объект не обладает этим атрибутом. Например, Если мы попытаемся использовать функцию upper() для целого числа, то получим ошибку атрибута.
Почему мы Получаем AttributeError?
Всякий раз, когда мы пытаемся получить доступ к атрибуту, который не принадлежит этому объекту, мы получаем attributeerror. Например, Мы знаем, что для того, чтобы сделать строку прописной, мы используем upper().
Выход-
AttributeError: 'int' object has no attribute 'upper'
Здесь мы пытаемся преобразовать целое число в заглавную букву, что невозможно, поскольку целые числа не приписывают быть верхними или нижними. Но если попытаться использовать эту функцию upper() для строки, мы получим результат, потому что строка может быть квалифицирована как верхняя или нижняя.
Если мы попытаемся выполнить append() для любого типа данных, отличного от List:
Иногда, когда мы хотим объединить две строки, мы пытаемся добавить одну строку в другую, что невозможно, и мы получаем ошибку атрибута.
Выход-
AttributeError: 'str' object has no attribute 'append'
То же самое относится и к кортежам,
Выход-
AttributeError: 'tuple' object has no attribute 'append'
Попытка доступа к атрибуту класса:
Иногда мы пытаемся получить доступ к атрибутам класса, которыми он не обладает. Давайте лучше разберемся в этом на примере.
Здесь у нас есть два класса — один-класс человека, а другой — класс транспортного средства. Оба обладают разными свойствами.
class Person: def __init__(self,age,gender,name): def speak(self): print("Hello!! How are you?") class Vehicle: def __init__(self , model_type , engine_type): def horn(self): print("beep!! beep") (20,"male","ashwini") print(ashwini.gender) print(ashwini.engine_type)
Выход-
male AttributeError: 'Person' object has no attribute 'engine_type'
AttributeError: 'Person' object has no attribute 'horn'
Выход-
Petrol AttributeError: 'Vehicle' object has no attribute 'gender'
Error- AttributeError: 'Vehicle' object has no attribute 'speak'
В приведенных выше примерах, когда мы попытались получить доступ к свойству пола класса Person, нам это удалось. Но когда мы попытались получить доступ к атрибуту engine_type (), он показал нам ошибку. Это происходит потому, что у человека нет атрибута под названием engine_type. Точно так же, когда мы попытались вызвать engine_type на транспортном средстве, мы добились успеха, но это было не в случае пола, так как Транспортное средство не имеет атрибута, называемого полом.
AttributeError: ‘NoneType’
Мы получаем ошибку NoneType, когда получаем «None» вместо экземпляра, который, как мы предполагаем, мы получим. Это означает, что задание провалилось или вернуло неожиданный результат.
Выход-
AttributeError: 'NoneType' object has no attribute 'upper'
При работе с модулями:
Очень часто при работе с модулями возникает ошибка атрибута. Предположим, мы импортируем модуль с именем hello и пытаемся получить доступ к двум функциям в нем. Один из них-print_name (), а другой-print_age().
Модуль Привет-
def print_name(): print("Hello! The name of this module is module1") import hello hello.print_name() hello.print_age()
Выход-
Hello! The name of this module is module1 AttributeError: module 'hello' has no attribute 'print_age'
Поскольку модуль hello не содержит атрибута print_age, мы получили атрибут Attributeerror. В следующем разделе мы узнаем, как устранить эту ошибку.
Как разрешить AttributeError в Python
Используйте справку():
Разработчики python пытались решить любую возможную проблему, с которой сталкиваются программисты Python. В этом случае также, если мы путаемся в том, принадлежит ли конкретный атрибут объекту или нет, мы можем использовать help(). Например, если мы не знаем, можем ли мы использовать append() для строки, мы можем print(help(str)) знать все операции, которые мы можем выполнять со строками. Не только эти встроенные типы данных, но мы также можем использовать help() для пользовательских типов данных, таких как Class.
Например, если мы не знаем, какими атрибутами обладает класс Person, объявленный нами выше,
Выход-
Разве это не здорово! Это именно те атрибуты, которые мы определили в нашем классе Персон.
Теперь давайте попробуем использовать help() для нашего модуля hello внутри модуля hi.
Help on module hello: NAME hello FUNCTIONS print_name()
Использование оператора Try – Except
Очень <сильный>профессиональный способ справиться не только с атрибутивной ошибкой, но и с любой ошибкой-это использовать try-except операторы. Если мы думаем, что можем получить ошибку в определенном блоке кода, мы можем заключить их в href=»https://en.wikipedia.org/wiki/Exception_handling»>попробуйте заблокировать. Давайте посмотрим, как это сделать. href=»https://en.wikipedia.org/wiki/Exception_handling»>попробуйте заблокировать. Давайте посмотрим, как это сделать.
Предположим, мы не уверены, содержит ли класс Person атрибут engine_type или нет, мы можем заключить его в блок try.
class Vehicle: def __init__(self , model_type , engine_type): def horn(self): print("beep!! beep") ( "Hatchback" , "Petrol" ) try: print(car.engine_type) print(car.gender) except Exception as e: print(e)
Выход-
Petrol 'Vehicle' object has no attribute 'gender'.
Должен Читать
- Как преобразовать строку в нижний регистр в
- Как вычислить Квадратный корень
- Пользовательский ввод | Функция ввода () | Ввод с клавиатуры
- Лучшая книга для изучения Python
Вывод
Всякий раз, когда мы пытаемся получить доступ к атрибуту объекта, который ему не принадлежит, мы получаем AttributeError в Python. Мы можем решить эту проблему с помощью функции help() или операторов try-except.
Попробуйте запустить программы на вашей стороне и дайте нам знать, если у вас есть какие-либо вопросы.
Счастливого кодирования!
In every programming language, if we develop new programs, there is a high chance of getting errors or exceptions. These errors yield to the program not being executed. One of the error in Python mostly occurs is “AttributeError”. AttributeError can be defined as an error that is raised when an attribute reference or assignment fails.
For example, if we take a variable x we are assigned a value of 10. In this process suppose we want to append another value to that variable. It’s not possible. Because the variable is an integer type it does not support the append method. So in this type of problem, we get an error called “AttributeError”. Suppose if the variable is list type then it supports the append method. Then there is no problem and not getting”Attribute error”.
Note: Attribute errors in Python are generally raised when an invalid attribute reference is made.
There are a few chances of getting AttributeError.
Example 1:
Python3
Output:
Traceback (most recent call last): File "/home/46576cfdd7cb1db75480a8653e2115cc.py", line 5, in X.append(6) AttributeError: 'int' object has no attribute 'append'
Example 2: Sometimes any variation in spelling will cause an Attribute error as Python is a case-sensitive language.
Python3
string
=
"The famous website is { }"
.fst(
"geeksforgeeks"
)
print
(string)
Output:
Traceback (most recent call last): File "/home/2078367df38257e2ec3aead22841c153.py", line 3, in string = "The famous website is { }".fst("geeksforgeeks") AttributeError: 'str' object has no attribute 'fst'
Example 3: AttributeError can also be raised for a user-defined class when the user tries to make an invalid attribute reference.
Python3
class
Geeks():
def
__init__(
self
):
self
.a
=
'GeeksforGeeks'
obj
=
Geeks()
print
(obj.a)
print
(obj.b)
Output:
GeeksforGeeks
Error:
Traceback (most recent call last): File "/home/373989a62f52a8b91cb2d3300f411083.py", line 17, in print(obj.b) AttributeError: 'Geeks' object has no attribute 'b'
Example 4: AttributeError can also be raised for a user-defined class when the user misses out on adding tabs or spaces between their lines of code.
Python3
class
dict_parsing:
def
__init__(
self
,a):
self
.a
=
a
def
getkeys(
self
):
if
self
.notdict():
return
list
(
self
.a.keys())
def
getvalues(
self
):
if
self
.notdict():
return
list
(
self
.a.values())
def
notdict(
self
):
if
type
(
self
.a) !
=
dict
:
raise
Exception(
self
,a,
'not a dictionary'
)
return
1
def
userinput(
self
):
self
.a
=
eval
(
input
())
print
(
self
.a,
type
(
self
.a))
print
(
self
.getykeys())
print
(
self
.getvalyes())
def
insertion(
self
,k,v):
self
.a[k]
=
v
d
=
dict_parsing({
"k1"
:
"amit"
,
"k2"
:[
1
,
2
,
3
,
4
,
5
]})
d.getkeys()
Output:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-9-c26cd169473f> in <module> ----> 1 d.getkeys() AttributeError: 'dict_parsing' object has no attribute 'getkeys'
Error:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-9-c26cd169473f> in <module> ----> 1 d.getkeys() AttributeError: 'dict_parsing' object has no attribute 'getkeys'
Solution for AttributeError
Errors and exceptions in Python can be handled using exception handling i.e. by using try and except in Python.
Example: Consider the above class example, we want to do something else rather than printing the traceback Whenever an AttributeError is raised.
Python3
class
Geeks():
def
__init__(
self
):
self
.a
=
'GeeksforGeeks'
obj
=
Geeks()
try
:
print
(obj.a)
print
(obj.b)
except
AttributeError:
print
(
"There is no such attribute"
)
Output:
GeeksforGeeks There is no such attribute
Note: To know more about exception handling click here.
Last Updated :
03 Jan, 2023
Like Article
Save Article
Обработка ошибок увеличивает отказоустойчивость кода, защищая его от потенциальных сбоев, которые могут привести к преждевременному завершению работы.
Прежде чем переходить к обсуждению того, почему обработка исключений так важна, и рассматривать встроенные в Python исключения, важно понять, что есть тонкая грань между понятиями ошибки и исключения.
Ошибку нельзя обработать, а исключения Python обрабатываются при выполнении программы. Ошибка может быть синтаксической, но существует и много видов исключений, которые возникают при выполнении и не останавливают программу сразу же. Ошибка может указывать на критические проблемы, которые приложение и не должно перехватывать, а исключения — состояния, которые стоит попробовать перехватить. Ошибки — вид непроверяемых и невозвратимых ошибок, таких как OutOfMemoryError
, которые не стоит пытаться обработать.
Обработка исключений делает код более отказоустойчивым и помогает предотвращать потенциальные проблемы, которые могут привести к преждевременной остановке выполнения. Представьте код, который готов к развертыванию, но все равно прекращает работу из-за исключения. Клиент такой не примет, поэтому стоит заранее обработать конкретные исключения, чтобы избежать неразберихи.
Ошибки могут быть разных видов:
- Синтаксические
- Недостаточно памяти
- Ошибки рекурсии
- Исключения
Разберем их по очереди.
Синтаксические ошибки (SyntaxError)
Синтаксические ошибки часто называют ошибками разбора. Они возникают, когда интерпретатор обнаруживает синтаксическую проблему в коде.
Рассмотрим на примере.
a = 8
b = 10
c = a b
File "", line 3
c = a b
^
SyntaxError: invalid syntax
Стрелка вверху указывает на место, где интерпретатор получил ошибку при попытке исполнения. Знак перед стрелкой указывает на причину проблемы. Для устранения таких фундаментальных ошибок Python будет делать большую часть работы за программиста, выводя название файла и номер строки, где была обнаружена ошибка.
Недостаточно памяти (OutofMemoryError)
Ошибки памяти чаще всего связаны с оперативной памятью компьютера и относятся к структуре данных под названием “Куча” (heap
). Если есть крупные объекты (или) ссылки на подобные, то с большой долей вероятности возникнет ошибка OutofMemory
. Она может появиться по нескольким причинам:
- Использование 32-битной архитектуры Python (максимальный объем выделенной памяти невысокий, между 2 и 4 ГБ);
- Загрузка файла большого размера;
- Запуск модели машинного обучения/глубокого обучения и много другое;
Обработать ошибку памяти можно с помощью обработки исключений — резервного исключения. Оно используется, когда у интерпретатора заканчивается память и он должен немедленно остановить текущее исполнение. В редких случаях Python вызывает OutofMemoryError
, позволяя скрипту каким-то образом перехватить самого себя, остановить ошибку памяти и восстановиться.
Но поскольку Python использует архитектуру управления памятью из языка C (функция malloc()
), не факт, что все процессы восстановятся — в некоторых случаях MemoryError
приведет к остановке. Следовательно, обрабатывать такие ошибки не рекомендуется, и это не считается хорошей практикой.
Ошибка рекурсии (RecursionError)
Эта ошибка связана со стеком и происходит при вызове функций. Как и предполагает название, ошибка рекурсии возникает, когда внутри друг друга исполняется много методов (один из которых — с бесконечной рекурсией), но это ограничено размером стека.
Все локальные переменные и методы размещаются в стеке. Для каждого вызова метода создается стековый кадр (фрейм), внутрь которого помещаются данные переменной или результат вызова метода. Когда исполнение метода завершается, его элемент удаляется.
Чтобы воспроизвести эту ошибку, определим функцию recursion
, которая будет рекурсивной — вызывать сама себя в бесконечном цикле. В результате появится ошибка StackOverflow
или ошибка рекурсии, потому что стековый кадр будет заполняться данными метода из каждого вызова, но они не будут освобождаться.
def recursion():
return recursion()
recursion()
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
in
----> 1 recursion()
in recursion()
1 def recursion():
----> 2 return recursion()
... last 1 frames repeated, from the frame below ...
in recursion()
1 def recursion():
----> 2 return recursion()
RecursionError: maximum recursion depth exceeded
Ошибка отступа (IndentationError)
Эта ошибка похожа по духу на синтаксическую и является ее подвидом. Тем не менее она возникает только в случае проблем с отступами.
Пример:
for i in range(10):
print('Привет Мир!')
File "", line 2
print('Привет Мир!')
^
IndentationError: expected an indented block
Исключения
Даже если синтаксис в инструкции или само выражение верны, они все равно могут вызывать ошибки при исполнении. Исключения Python — это ошибки, обнаруживаемые при исполнении, но не являющиеся критическими. Скоро вы узнаете, как справляться с ними в программах Python. Объект исключения создается при вызове исключения Python. Если скрипт не обрабатывает исключение явно, программа будет остановлена принудительно.
Программы обычно не обрабатывают исключения, что приводит к подобным сообщениям об ошибке:
Ошибка типа (TypeError)
a = 2
b = 'PythonRu'
a + b
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in
1 a = 2
2 b = 'PythonRu'
----> 3 a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Ошибка деления на ноль (ZeroDivisionError)
10 / 0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
in
----> 1 10 / 0
ZeroDivisionError: division by zero
Есть разные типы исключений в Python и их тип выводится в сообщении: вверху примеры TypeError
и ZeroDivisionError
. Обе строки в сообщениях об ошибке представляют собой имена встроенных исключений Python.
Оставшаяся часть строки с ошибкой предлагает подробности о причине ошибки на основе ее типа.
Теперь рассмотрим встроенные исключения Python.
Встроенные исключения
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
Прежде чем переходить к разбору встроенных исключений быстро вспомним 4 основных компонента обработки исключения, как показано на этой схеме.
Try
: он запускает блок кода, в котором ожидается ошибка.Except
: здесь определяется тип исключения, который ожидается в блокеtry
(встроенный или созданный).Else
: если исключений нет, тогда исполняется этот блок (его можно воспринимать как средство для запуска кода в том случае, если ожидается, что часть кода приведет к исключению).Finally
: вне зависимости от того, будет ли исключение или нет, этот блок кода исполняется всегда.
В следующем разделе руководства больше узнаете об общих типах исключений и научитесь обрабатывать их с помощью инструмента обработки исключения.
Ошибка прерывания с клавиатуры (KeyboardInterrupt)
Исключение KeyboardInterrupt
вызывается при попытке остановить программу с помощью сочетания Ctrl + C
или Ctrl + Z
в командной строке или ядре в Jupyter Notebook. Иногда это происходит неумышленно и подобная обработка поможет избежать подобных ситуаций.
В примере ниже если запустить ячейку и прервать ядро, программа вызовет исключение KeyboardInterrupt
. Теперь обработаем исключение KeyboardInterrupt
.
try:
inp = input()
print('Нажмите Ctrl+C и прервите Kernel:')
except KeyboardInterrupt:
print('Исключение KeyboardInterrupt')
else:
print('Исключений не произошло')
Исключение KeyboardInterrupt
Стандартные ошибки (StandardError)
Рассмотрим некоторые базовые ошибки в программировании.
Арифметические ошибки (ArithmeticError)
- Ошибка деления на ноль (Zero Division);
- Ошибка переполнения (OverFlow);
- Ошибка плавающей точки (Floating Point);
Все перечисленные выше исключения относятся к классу Arithmetic
и вызываются при ошибках в арифметических операциях.
Деление на ноль (ZeroDivisionError)
Когда делитель (второй аргумент операции деления) или знаменатель равны нулю, тогда результатом будет ошибка деления на ноль.
try:
a = 100 / 0
print(a)
except ZeroDivisionError:
print("Исключение ZeroDivisionError." )
else:
print("Успех, нет ошибок!")
Исключение ZeroDivisionError.
Переполнение (OverflowError)
Ошибка переполнение вызывается, когда результат операции выходил за пределы диапазона. Она характерна для целых чисел вне диапазона.
try:
import math
print(math.exp(1000))
except OverflowError:
print("Исключение OverFlow.")
else:
print("Успех, нет ошибок!")
Исключение OverFlow.
Ошибка утверждения (AssertionError)
Когда инструкция утверждения не верна, вызывается ошибка утверждения.
Рассмотрим пример. Предположим, есть две переменные: a
и b
. Их нужно сравнить. Чтобы проверить, равны ли они, необходимо использовать ключевое слово assert
, что приведет к вызову исключения Assertion
в том случае, если выражение будет ложным.
try:
a = 100
b = "PythonRu"
assert a == b
except AssertionError:
print("Исключение AssertionError.")
else:
print("Успех, нет ошибок!")
Исключение AssertionError.
Ошибка атрибута (AttributeError)
При попытке сослаться на несуществующий атрибут программа вернет ошибку атрибута. В следующем примере можно увидеть, что у объекта класса Attributes
нет атрибута с именем attribute
.
class Attributes(obj):
a = 2
print(a)
try:
obj = Attributes()
print(obj.attribute)
except AttributeError:
print("Исключение AttributeError.")
2
Исключение AttributeError.
Ошибка импорта (ModuleNotFoundError)
Ошибка импорта вызывается при попытке импортировать несуществующий (или неспособный загрузиться) модуль в стандартном пути или даже при допущенной ошибке в имени.
import nibabel
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
in
----> 1 import nibabel
ModuleNotFoundError: No module named 'nibabel'
Ошибка поиска (LookupError)
LockupError
выступает базовым классом для исключений, которые происходят, когда key
или index
используются для связывания или последовательность списка/словаря неверна или не существует.
Здесь есть два вида исключений:
- Ошибка индекса (
IndexError
); - Ошибка ключа (
KeyError
);
Ошибка ключа
Если ключа, к которому нужно получить доступ, не оказывается в словаре, вызывается исключение KeyError
.
try:
a = {1:'a', 2:'b', 3:'c'}
print(a[4])
except LookupError:
print("Исключение KeyError.")
else:
print("Успех, нет ошибок!")
Исключение KeyError.
Ошибка индекса
Если пытаться получить доступ к индексу (последовательности) списка, которого не существует в этом списке или находится вне его диапазона, будет вызвана ошибка индекса (IndexError: list index out of range python).
try:
a = ['a', 'b', 'c']
print(a[4])
except LookupError:
print("Исключение IndexError, индекс списка вне диапазона.")
else:
print("Успех, нет ошибок!")
Исключение IndexError, индекс списка вне диапазона.
Ошибка памяти (MemoryError)
Как уже упоминалось, ошибка памяти вызывается, когда операции не хватает памяти для выполнения.
Ошибка имени (NameError)
Ошибка имени возникает, когда локальное или глобальное имя не находится.
В следующем примере переменная ans
не определена. Результатом будет ошибка NameError
.
try:
print(ans)
except NameError:
print("NameError: переменная 'ans' не определена")
else:
print("Успех, нет ошибок!")
NameError: переменная 'ans' не определена
Ошибка выполнения (Runtime Error)
Ошибка «NotImplementedError»
Ошибка выполнения служит базовым классом для ошибки NotImplemented
. Абстрактные методы определенного пользователем класса вызывают это исключение, когда производные методы перезаписывают оригинальный.
class BaseClass(object):
"""Опередляем класс"""
def __init__(self):
super(BaseClass, self).__init__()
def do_something(self):
# функция ничего не делает
raise NotImplementedError(self.__class__.__name__ + '.do_something')
class SubClass(BaseClass):
"""Реализует функцию"""
def do_something(self):
# действительно что-то делает
print(self.__class__.__name__ + ' что-то делает!')
SubClass().do_something()
BaseClass().do_something()
SubClass что-то делает!
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
in
14
15 SubClass().do_something()
---> 16 BaseClass().do_something()
in do_something(self)
5 def do_something(self):
6 # функция ничего не делает
----> 7 raise NotImplementedError(self.__class__.__name__ + '.do_something')
8
9 class SubClass(BaseClass):
NotImplementedError: BaseClass.do_something
Ошибка типа (TypeError)
Ошибка типа вызывается при попытке объединить два несовместимых операнда или объекта.
В примере ниже целое число пытаются добавить к строке, что приводит к ошибке типа.
try:
a = 5
b = "PythonRu"
c = a + b
except TypeError:
print('Исключение TypeError')
else:
print('Успех, нет ошибок!')
Исключение TypeError
Ошибка значения (ValueError)
Ошибка значения вызывается, когда встроенная операция или функция получают аргумент с корректным типом, но недопустимым значением.
В этом примере встроенная операция float
получат аргумент, представляющий собой последовательность символов (значение), что является недопустимым значением для типа: число с плавающей точкой.
try:
print(float('PythonRu'))
except ValueError:
print('ValueError: не удалось преобразовать строку в float: 'PythonRu'')
else:
print('Успех, нет ошибок!')
ValueError: не удалось преобразовать строку в float: 'PythonRu'
Пользовательские исключения в Python
В Python есть много встроенных исключений для использования в программе. Но иногда нужно создавать собственные со своими сообщениями для конкретных целей.
Это можно сделать, создав новый класс, который будет наследовать из класса Exception
в Python.
class UnAcceptedValueError(Exception):
def __init__(self, data):
self.data = data
def __str__(self):
return repr(self.data)
Total_Marks = int(input("Введите общее количество баллов: "))
try:
Num_of_Sections = int(input("Введите количество разделов: "))
if(Num_of_Sections < 1):
raise UnAcceptedValueError("Количество секций не может быть меньше 1")
except UnAcceptedValueError as e:
print("Полученная ошибка:", e.data)
Введите общее количество баллов: 10
Введите количество разделов: 0
Полученная ошибка: Количество секций не может быть меньше 1
В предыдущем примере если ввести что-либо меньше 1, будет вызвано исключение. Многие стандартные исключения имеют собственные исключения, которые вызываются при возникновении проблем в работе их функций.
Недостатки обработки исключений в Python
У использования исключений есть свои побочные эффекты, как, например, то, что программы с блоками try-except работают медленнее, а количество кода возрастает.
Дальше пример, где модуль Python timeit
используется для проверки времени исполнения 2 разных инструкций. В stmt1
для обработки ZeroDivisionError
используется try-except, а в stmt2
— if
. Затем они выполняются 10000 раз с переменной a=0
. Суть в том, чтобы показать разницу во времени исполнения инструкций. Так, stmt1
с обработкой исключений занимает больше времени чем stmt2
, который просто проверяет значение и не делает ничего, если условие не выполнено.
Поэтому стоит ограничить использование обработки исключений в Python и применять его в редких случаях. Например, когда вы не уверены, что будет вводом: целое или число с плавающей точкой, или не уверены, существует ли файл, который нужно открыть.
import timeit
setup="a=0"
stmt1 = '''
try:
b=10/a
except ZeroDivisionError:
pass'''
stmt2 = '''
if a!=0:
b=10/a'''
print("time=",timeit.timeit(stmt1,setup,number=10000))
print("time=",timeit.timeit(stmt2,setup,number=10000))
time= 0.003897680000136461
time= 0.0002797570000439009
Выводы!
Как вы могли увидеть, обработка исключений помогает прервать типичный поток программы с помощью специального механизма, который делает код более отказоустойчивым.
Обработка исключений — один из основных факторов, который делает код готовым к развертыванию. Это простая концепция, построенная всего на 4 блоках: try
выискивает исключения, а except
их обрабатывает.
Очень важно поупражняться в их использовании, чтобы сделать свой код более отказоустойчивым.
I have crossed with this issue many times, but I didnt try to dig deeper about it. Now I understand the main issue.
This time my problem was importing Serializers ( django and restframework ) from different modules such as the following :
from rest_framework import serializers
from common import serializers as srlz
from prices import models as mdlpri
# the line below was the problem 'srlzprod'
from products import serializers as srlzprod
I was getting a problem like this :
from product import serializers as srlzprod
ModuleNotFoundError: No module named 'product'
What I wanted to accomplished was the following :
class CampaignsProductsSerializers(srlz.DynamicFieldsModelSerializer):
bank_name = serializers.CharField(trim_whitespace=True,)
coupon_type = serializers.SerializerMethodField()
promotion_description = serializers.SerializerMethodField()
# the nested relation of the line below
product = srlzprod.ProductsSerializers(fields=['id','name',],read_only=True,)
So, as mentioned by the lines above how to solve it ( top-level import ), I proceed to do the following changes :
# change
product = srlzprod.ProductsSerializers(fields=['id','name',],read_only=True,)
# by
product = serializers.SerializerMethodField()
# and create the following method and call from there the required serializer class
def get_product(self, obj):
from products import serializers as srlzprod
p_fields = ['id', 'name', ]
return srlzprod.ProductsSerializers(
obj.product, fields=p_fields, many=False,
).data
Therefore, django runserver was executed without problems :
./project/settings/manage.py runserver 0:8002 --settings=settings_development_mlazo
Performing system checks...
System check identified no issues (0 silenced).
April 25, 2020 - 13:31:56
Django version 2.0.7, using settings 'settings_development_mlazo'
Starting development server at http://0:8002/
Quit the server with CONTROL-C.
Final state of the code lines was the following :
from rest_framework import serializers
from common import serializers as srlz
from prices import models as mdlpri
class CampaignsProductsSerializers(srlz.DynamicFieldsModelSerializer):
bank_name = serializers.CharField(trim_whitespace=True,)
coupon_type = serializers.SerializerMethodField()
promotion_description = serializers.SerializerMethodField()
product = serializers.SerializerMethodField()
class Meta:
model = mdlpri.CampaignsProducts
fields = '__all__'
def get_product(self, obj):
from products import serializers as srlzprod
p_fields = ['id', 'name', ]
return srlzprod.ProductsSerializers(
obj.product, fields=p_fields, many=False,
).data
Hope this could be helpful for everybody else.
Greetings,
We raise a Python AttributeError when we try to call or access an attribute of an object that does not exist for that object.
This tutorial will go through what an attribute is, what the AttributeError is in detail, and we will go through four examples to learn how to solve the error.
Table of contents
- What is a Python AttributeError?
- Example #1: Trying to Use append() on a String
- Solution
- Example #2: Trying to Access an Attribute of a Class that does not exist
- Solution
- Example #3: NoneType Object has no Attribute
- Solution
- Example #4: Handling Modules
- Solution
- Summary
What is a Python AttributeError?
An attribute of an object is a value or a function associated with that object. We can express calling a method of a class as referencing an attribute of a class.
Let’s look at an example of a Python class for the particle electron
class Electron:
def __init__(self):
self.charge = -1
self.mass = 0.51
self.spin = 1/2
def positron(self):
self.charge = +1
return self.charge
We can think of an attribute in Python as a physical attribute of an object. In this example, the fundamental particle, the electron, has physical attributes of charge, mass, and spin. The Electron class has the attributes charge, mass, and spin.
An attribute can also be a function. The function positron() returns the charge of the electron’s anti-particle, the positron.
Data types can have attributes. For example, the built-in data type List has the append() method to append elements to an existing list. Therefore, List objects support the append() method. Let’s look at an example of appending to a list:
a_list = [2, 4, 6]
a_list.append(8)
print(a_list)
Attributes have to exist for a class object or a data type for you to reference it. If the attribute is not associated with a class object or data type, you will raise an AttributeError.
Example #1: Trying to Use append() on a String
Let’s look at an example scenario where we concatenate two strings by appending one string to another.
string1 = "research"
string2 = "scientist"
string1.append(string2)
Using append() is impossible because the string data type does not have the append() method. Let’s run the code to see what happens:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
1 string1.append(string2)
AttributeError: 'str' object has no attribute 'append'
Solution
To solve this problem, we need to define a third string. We can then concatenate the two strings using the + symbol and assign the result to the third string. We can concatenate a space between the two strings so that the words do not run together. Let’s look at how the revised code:
string1 = "research"
string2 = "scientist"
string3 = string1 + " " + string2
print(string3)
research scientist
Example #2: Trying to Access an Attribute of a Class that does not exist
Let’s look at an example scenario where we want to access an attribute of a class that does not exist. We can try to create an instance of the class Electron from earlier in the tutorial. Once we have the instance, we can try to use the function get_mass() to print the mass of the electron in MeV.
class Electron:
def __init__(self):
self.charge = -1
self.mass = 0.51
self.spin = 1/2
def positron(self):
self.charge = +1
return self.charge
electron = Electron()
mass = electron.get_mass()
If we try to run the code, we get the following error:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
1 mass = electron.get_mass()
AttributeError: 'Electron' object has no attribute 'get_mass'
The Electron class has no attribute called get_mass(). Therefore we raise an AttributeError.
Solution
To solve this, we can do two things. We can add the method to the class and use a try-except statement. First, let’s look at adding the method:
class Electron:
def __init__(self):
self.charge = -1
self.mass = 0.51
self.spin = 1/2
def positron(self):
self.charge = +1
return self.charge
def get_mass(self):
return self.mass
electron = Electron()
mass = electron.get_mass()
print(f' The mass of the electron is {mass} MeV')
The mass of the electron is 0.51 MeV
Secondly, let’s look at using try-except to catch the AttributeError. We can use try-except statements to catch any error, not just AttributeError. Suppose we want to use a method called get_charge() to get the charge of the electron object, but we are not sure whether the Electron class contains the get_charge() attribute. We can enclose the call to get_charge() in a try-except statement.
class Electron:
def __init__(self):
self.charge = -1
self.mass = 0.51
self.spin = 1/2
def positron(self):
self.charge = +1
return self.charge
def get_mass(self):
return self.mass
electron = Electron()
try:
charge = electron.get_charge()
except Exception as e:
print(e)
'Electron' object has no attribute 'get_charge'
Using try-except statements aligns with professional development and makes your programs less prone to crashing.
Example #3: NoneType Object has no Attribute
NoneType means that whatever class or object you are trying to access is None. Therefore, whenever you try to do a function call or an assignment for that object, it will raise the AttributeError: ‘NoneType’ object has no attribute. Let’s look at an example scenario for a specific NoneType attribute error. We will write a program that uses regular expressions to search for an upper case “S” character at the beginning and print the word. We need to import the module re for regular expression matching.
import re
# Search for an upper case "S" character in the beginning of a word then print the word
string = "Research Scientist"
for i in string.split():
x = re.match(r"bSw+", i)
print(x.group())
Let’s run the code and see what happens:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
1 for i in string.split():
2 x = re.match(r"bSw+", i)
3 print(x.group())
4
AttributeError: 'NoneType' object has no attribute 'group'
We raise the AttributeError because there is no match in the first iteration. Therefore x returns None. The attribute group() does not belong to NoneType objects.
Solution
To solve this error, we want to only call group() for the situation where there is a match to the regular expression. We can therefore use the try-except block to handle the AttributeError. We can use continue to skip when x returns None in the for loop. Let’s look at the revised code.
import re
# Search for an upper case "S" character in the beginning of a word then print the word
string = "Research Scientist"
for i in string.split():
x = re.match(r"bSw+", i)
try:
print(x.group())
except AttributeError:
continue
Scientist
We can see that the code prints out Scientist, which is the word that has an upper case “S” character.
Example #4: Handling Modules
We can encounter an AttributeError while working with modules because we may call a function that does not exist for a module. Let’s look at an example of importing the math module and calling a function to perform a square root.
import math
number = 9
square_root_number = math.square_root(number)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
1 square_root_number = math.square_root(number)
AttributeError: module 'math' has no attribute 'square_root'
The module math does not contain the attribute square_root. Therefore we get an AttributeError.
Solution
To solve this error, you can use the help() function to get the module’s documentation, including the functions that belong to the module. We can use the help function on the math module to see which function corresponds to the square root.
import math
help(math)
sqrt(x, /)
Return the square root of x.
The function’s name to return the square root of a number is sqrt(). We can use this function in place of the incorrect function name.
square_root_number = math.sqrt(number)
print(square_root_number)
3.0
The code successfully returns the square root of 9. You can also use help() on classes defined in your program. Let’s look at the example of using help() on the Electron class.
help(Electron)
class Electron(builtins.object)
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| get_mass(self)
|
| positron(self)
The help() function returns the methods defined for the Electron class.
Summary
Congratulations on reading to the end of this tutorial. Attribute errors occur in Python when you try to reference an invalid attribute.
- If the attribute you want for built-in data types does not exist, you should look for an attribute that does something similar. For example, there is no append() method for strings but you can use concatenation to combine strings.
- For classes that are defined in your code, you can use help() to find out if an attribute exists before trying to reference it. If it does not exist you can add it to your class and then create a new instance of the class.
- If you are not sure if a function or value does not exist or if a code block may return a NoneType object, you can wrap the code in a try-except statement. Using a try-except stops your program from crashing if you raise an AttributeError.
For further reading on AttributeError, you can go to the following article: How to Solve Python AttributeError: ‘list’ object has no attribute ‘split’
Go to the online courses page on Python to learn more about Python for data science and machine learning.
Have fun and happy researching!