Traceback в python

Summing Up

After seeing the difference between syntax errors and exceptions, you learned about various ways to raise, catch, and handle exceptions in Python. In this article, you saw the following options:


  • allows you to throw an exception at any time.
  • enables you to verify if a certain condition is met and throw an exception if it isn’t.
  • In the clause, all statements are executed until an exception is encountered.
  • is used to catch and handle the exception(s) that are encountered in the try clause.
  • lets you code sections that should run only when no exceptions are encountered in the try clause.
  • enables you to execute sections of code that should always run, with or without any previously encountered exceptions.

Free PDF Download: Python 3 Cheat Sheet

Handling an exception

If you have some suspicious code that may raise an exception, you can defend your program by placing the suspicious code in a try: block. After the try: block, include an except: statement, followed by a block of code which handles the problem as elegantly as possible.

Syntax

Here is simple syntax of try….except…else blocks −

try:
   You do your operations here;
   ......................
except ExceptionI:
   If there is ExceptionI, then execute this block.
except ExceptionII:
   If there is ExceptionII, then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

Here are few important points about the above-mentioned syntax −

  • A single try statement can have multiple except statements. This is useful when the try block contains statements that may throw different types of exceptions.

  • You can also provide a generic except clause, which handles any exception.

  • After the except clause(s), you can include an else-clause. The code in the else-block executes if the code in the try: block does not raise an exception.

  • The else-block is a good place for code that does not need the try: block’s protection.

Example

This example opens a file, writes content in the, file and comes out gracefully because there is no problem at all −

#!/usr/bin/python

try:
   fh = open("testfile", "w")
   fh.write("This is my test file for exception handling!!")
except IOError:
   print "Error: can\'t find file or read data"
else:
   print "Written content in the file successfully"
   fh.close()

This produces the following result −

Written content in the file successfully

Example

This example tries to open a file where you do not have write permission, so it raises an exception −

#!/usr/bin/python

try:
   fh = open("testfile", "r")
   fh.write("This is my test file for exception handling!!")
except IOError:
   print "Error: can\'t find file or read data"
else:
   print "Written content in the file successfully"

This produces the following result −

Error: can't find file or read data

Errors and Exceptions

Exception Handling

An exception is an error that happens during the execution of a program. Exceptions are known to non-programmers as instances that do not conform to a general rule. The name «exception» in computer science has this meaning as well: It implies that the problem (the exception) doesn’t occur frequently, i.e. the exception is the «exception to the rule». Exception handling is a construct in some programming languages to handle or deal with errors automatically. Many programming languages like C++, Objective-C, PHP, Java, Ruby, Python, and many others have built-in support for exception handling.

Error handling is generally resolved by saving the state of execution at the moment the error occurred and interrupting the normal flow of the program to execute a special function or piece of code, which is known as the exception handler. Depending on the kind of error («division by zero», «file open error» and so on) which had occurred, the error handler can «fix» the problem and the programm can be continued afterwards with the previously saved data.

Exception Handling in Python

Exception handling in Python is very similar to Java. The code, which harbours the risk of an exception, is embedded in a try block. While in Java exceptions are caught by catch clauses, in Python we have statements introduced by an «except» keyword. It’s possible to create «custom-made» exceptions: With the raise statement it’s possible to force a specified exception to occur.


Let’s look at a simple example. Assuming we want to ask the user to enter an integer number. If we use a input(), the input will be a string, which we have to cast into an integer. If the input isn’t a valid integer, we will generate (raise) a ValueError. We show this in the following interactive session:

Python NumPy

NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random Random Intro Data Distribution Random Permutation Seaborn Module Normal Distribution Binomial Distribution Poisson Distribution Uniform Distribution Logistic Distribution Multinomial Distribution Exponential Distribution Chi Square Distribution Rayleigh Distribution Pareto Distribution Zipf Distribution

NumPy ufunc ufunc Intro ufunc Create Function ufunc Simple Arithmetic ufunc Rounding Decimals ufunc Logs ufunc Summations ufunc Products ufunc Differences ufunc Finding LCM ufunc Finding GCD ufunc Trigonometric ufunc Hyperbolic ufunc Set Operations

Raising an Exception

You can raise exceptions in several ways by using the raise statement. The general syntax for the raise statement is as follows −

Syntax

raise ]]

Here, Exception is the type of exception (for example, NameError) and argument is a value for the exception argument. The argument is optional; if not supplied, the exception argument is None.

The final argument, traceback, is also optional (and rarely used in practice), and if present, is the traceback object used for the exception.

Example

An exception can be a string, a class or an object. Most of the exceptions that the Python core raises are classes, with an argument that is an instance of the class. Defining new exceptions is quite easy and can be done as follows −

def functionName( level ):
   if level <1:
      raise Exception(level)
      # The code below to this would not be executed
      # if we raise the exception
   return level

Note − In order to catch an exception, an «except» clause must refer to the same exception thrown either as a class object or a simple string. For example, to capture the above exception, we must write the except clause as follows −

try:
   Business Logic here...
except Exception as e:
   Exception handling here using e.args...
else:
   Rest of the code here...

The following example illustrates the use of raising an exception

#!/usr/bin/python3

def functionName( level ):
   if level <1:
      raise Exception(level)
      # The code below to this would not be executed
      # if we raise the exception
   return level

try:
   l = functionName(-10)
   print ("level = ",l)
except Exception as e:
   print ("error in level argument",e.args)

This will produce the following result

error in level argument -10

Making return-triggered StopIterations obvious

For certain situations, a simpler and fully backward-compatible solution may be sufficient: when a generator returns, instead of raising StopIteration, it raises a specific subclass of StopIteration (GeneratorReturn) which can then be detected. If it is not that subclass, it is an escaping exception rather than a return statement.

The inspiration for this alternative proposal was Nick’s observation that if an asyncio coroutine accidentally raises StopIteration, it currently terminates silently, which may present a hard-to-debug mystery to the developer. The main proposal turns such accidents into clearly distinguishable RuntimeError exceptions, but if that is rejected, this alternate proposal would enable asyncio to distinguish between a return statement and an accidentally-raised StopIteration exception.

Of the three outcomes listed above, two change:

  • If a yield point is reached, the value, obviously, would still be returned.
  • If the frame is returned from, GeneratorReturn (rather than StopIteration) is raised.
  • If an instance of GeneratorReturn would be raised, instead an instance of StopIteration would be raised. Any other exception bubbles up normally.

In the third case, the StopIteration would have the value of the original GeneratorReturn, and would reference the original exception in its __cause__. If uncaught, this would clearly show the chaining of exceptions.

This alternative does not affect the discrepancy between generator expressions and list comprehensions, but allows generator-aware code (such as the contextlib and asyncio modules) to reliably differentiate between the second and third outcomes listed above.

The try-finally Clause

You can use a finally: block along with a try: block. The finally: block is a place to put any code that must execute, whether the try-block raised an exception or not. The syntax of the try-finally statement is this −

try:
   You do your operations here;
   ......................
   Due to any exception, this may be skipped.
finally:
   This would always be executed.
   ......................

Note − You can provide except clause(s), or a finally clause, but not both. You cannot use else clause as well along with a finally clause.

Example

#!/usr/bin/python3

try:
   fh = open("testfile", "w")
   fh.write("This is my test file for exception handling!!")
finally:
   print ("Error: can\'t find file or read data")
   fh.close()

If you do not have permission to open the file in writing mode, then this will produce the following result −

Error: can't find file or read data

Same example can be written more cleanly as follows −

#!/usr/bin/python3

try:
   fh = open("testfile", "w")
   try:
      fh.write("This is my test file for exception handling!!")
   finally:
      print ("Going to close the file")
      fh.close()
except IOError:
   print ("Error: can\'t find file or read data")

This produces the following result −

Going to close the file

When an exception is thrown in the try block, the execution immediately passes to the finally block. After all the statements in the finally block are executed, the exception is raised again and is handled in the except statements if present in the next higher layer of the try-except statement.

Examples of breakage

Generators which explicitly raise StopIteration can generally be changed to simply return instead. This will be compatible with all existing Python versions, and will not be affected by __future__. Here are some illustrations from the standard library.


Lib/ipaddress.py:

if other == self:
    raise StopIteration

Becomes:

if other == self:
    return

In some cases, this can be combined with yield from to simplify the code, such as Lib/difflib.py:

if context is None:
    while True:
        yield next(line_pair_iterator)

Becomes:

if context is None:
    yield from line_pair_iterator
    return

(The return is necessary for a strictly-equivalent translation, though in this particular file, there is no further code, and the return can be omitted.) For compatibility with pre-3.3 versions of Python, this could be written with an explicit for loop:

if context is None:
    for line in line_pair_iterator:
        yield line
    return

More complicated iteration patterns will need explicit try/except constructs. For example, a hypothetical parser like this:

def parser(f):
    while True:
        data = next(f)
        while True:
            line = next(f)
            if line == "- end -": break
            data += line
        yield data

would need to be rewritten as:

def parser(f):
    while True:
        try:
            data = next(f)
            while True:
                line = next(f)
                if line == "- end -": break
                data += line
            yield data
        except StopIteration:
            return

or possibly:

def parser(f):
    for data in f:
        while True:
            line = next(f)
            if line == "- end -": break
            data += line
        yield data

The latter form obscures the iteration by purporting to iterate over the file with a for loop, but then also fetches more data from the same iterator during the loop body. It does, however, clearly differentiate between a «normal» termination (StopIteration instead of the initial line) and an «abnormal» termination (failing to find the end marker in the inner loop, which will now raise RuntimeError).

This effect of StopIteration has been used to cut a generator expression short, creating a form of takewhile:

def stop():
    raise StopIteration
print(list(x for x in range(10) if x < 5 or stop()))
# prints 

Under the current proposal, this form of non-local flow control is not supported, and would have to be rewritten in statement form:

def gen():
    for x in range(10):
        if x >= 5: return
        yield x
print(list(gen()))
# prints 

Multiple except clauses

An examination of use-cases shows that this is not needed as often as it would be with the statement form, and as its syntax is a point on which consensus has not been reached, the entire feature is deferred.

Multiple ‘except’ keywords could be used, and they will all catch exceptions raised in the original expression (only):

# Will catch any of the listed exceptions thrown by expr;
# any exception thrown by a default expression will propagate.
value = (expr
    except Exception1: default1
    except Exception2: default2
    # ... except ExceptionN: defaultN
)

Currently, one of the following forms must be used:

# Will catch an Exception2 thrown by either expr or default1
value = (
    (expr except Exception1: default1)
    except Exception2: default2
)
# Will catch an Exception2 thrown by default1 only
value = (expr except Exception1:
    (default1 except Exception2: default2)
)

Raising an Exceptions

You can raise exceptions in several ways by using the raise statement. The general syntax for the raise statement is as follows.

Syntax

raise ]]

Here, Exception is the type of exception (for example, NameError) and argument is a value for the exception argument. The argument is optional; if not supplied, the exception argument is None.

The final argument, traceback, is also optional (and rarely used in practice), and if present, is the traceback object used for the exception.

Example

An exception can be a string, a class or an object. Most of the exceptions that the Python core raises are classes, with an argument that is an instance of the class. Defining new exceptions is quite easy and can be done as follows −

def functionName( level ):
   if level < 1:
      raise "Invalid level!", level
      # The code below to this would not be executed
      # if we raise the exception

Note: In order to catch an exception, an «except» clause must refer to the same exception thrown either class object or simple string. For example, to capture above exception, we must write the except clause as follows −

try:
   Business Logic here...
except "Invalid level!":
   Exception handling here...
else:
   Rest of the code here...

Python NumPy

NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random Random Intro Data Distribution Random Permutation Seaborn Module Normal Distribution Binomial Distribution Poisson Distribution Uniform Distribution Logistic Distribution Multinomial Distribution Exponential Distribution Chi Square Distribution Rayleigh Distribution Pareto Distribution Zipf Distribution

NumPy ufunc ufunc Intro ufunc Create Function ufunc Simple Arithmetic ufunc Rounding Decimals ufunc Logs ufunc Summations ufunc Products ufunc Differences ufunc Finding LCM ufunc Finding GCD ufunc Trigonometric ufunc Hyperbolic ufunc Set Operations

User-Defined Exceptions

Python also allows you to create your own exceptions by deriving classes from the standard built-in exceptions.

Here is an example related to RuntimeError. Here, a class is created that is subclassed from RuntimeError. This is useful when you need to display more specific information when an exception is caught.

In the try block, the user-defined exception is raised and caught in the except block. The variable e is used to create an instance of the class Networkerror.

class Networkerror(RuntimeError):
   def __init__(self, arg):
      self.args = arg

So once you defined above class, you can raise the exception as follows −

try:
   raise Networkerror("Bad hostname")
except Networkerror,e:
   print e.args

Previous Page Print Page

Next Page  

Argument of an Exception

An exception can have an argument, which is a value that gives additional information about the problem. The contents of the argument vary by exception. You capture an exception’s argument by supplying a variable in the except clause as follows −

try:
   You do your operations here
   ......................
except ExceptionType as Argument:
   You can print value of Argument here...

If you write the code to handle a single exception, you can have a variable follow the name of the exception in the except statement. If you are trapping multiple exceptions, you can have a variable follow the tuple of the exception.

This variable receives the value of the exception mostly containing the cause of the exception. The variable can receive a single value or multiple values in the form of a tuple. This tuple usually contains the error string, the error number, and an error location.

Example

Following is an example for a single exception −

#!/usr/bin/python3

# Define a function here.
def temp_convert(var):
   try:
      return int(var)
   except ValueError as Argument:
      print ("The argument does not contain numbers\n", Argument)

# Call above function here.
temp_convert("xyz")

This produces the following result −

The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'

Argument of an Exception

An exception can have an argument, which is a value that gives additional information about the problem. The contents of the argument vary by exception. You capture an exception’s argument by supplying a variable in the except clause as follows −

try:
   You do your operations here;
   ......................
except ExceptionType, Argument:
   You can print value of Argument here...

If you write the code to handle a single exception, you can have a variable follow the name of the exception in the except statement. If you are trapping multiple exceptions, you can have a variable follow the tuple of the exception.

This variable receives the value of the exception mostly containing the cause of the exception. The variable can receive a single value or multiple values in the form of a tuple. This tuple usually contains the error string, the error number, and an error location.

Example

Following is an example for a single exception −

#!/usr/bin/python

# Define a function here.
def temp_convert(var):
   try:
      return int(var)
   except ValueError, Argument:
      print "The argument does not contain numbers\n", Argument

# Call above function here.
temp_convert("xyz");

This produces the following result −

The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'

Python NumPy

NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random Random Intro Data Distribution Random Permutation Seaborn Module Normal Distribution Binomial Distribution Poisson Distribution Uniform Distribution Logistic Distribution Multinomial Distribution Exponential Distribution Chi Square Distribution Rayleigh Distribution Pareto Distribution Zipf Distribution

NumPy ufunc ufunc Intro ufunc Create Function ufunc Simple Arithmetic ufunc Rounding Decimals ufunc Logs ufunc Summations ufunc Products ufunc Differences ufunc Finding LCM ufunc Finding GCD ufunc Trigonometric ufunc Hyperbolic ufunc Set Operations

Заключение

Трассировка содержит важную информацию, которая может помочь вам найти, что идет не так в вашем коде. Эти следы могут выглядеть немного пугающими, но как только вы разберетесь с ними, чтобы увидеть, что они пытаются вам показать, они могут быть очень полезными. Изучение нескольких трассировок построчно даст вам лучшее понимание информации, которую они содержат, и поможет вам извлечь из них максимальную пользу.

Получение вывода трассировки при запуске вашего кода — это отличная возможность улучшить ваш код.

Теперь, когда вы знаете, как читать трассировку, вы можете больше узнать о некоторых инструментах и методах диагностики проблем, о которых рассказывает ваш вывод трассировки. Встроенный модуль может использоваться для работы и проверки трассировок. Модуль трассировки может быть полезен, когда вам нужно получить больше от результатов трассировки. Также было бы полезно узнать больше о некоторых методах отладки кода Python.

Spread the love


С этим читают