exceptions.asciidoc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. [[exceptions]]
  2. == Exceptions
  3. Exceptions occur when _exceptional_ situations occur in your program. For example, what if you are
  4. going to read a file and the file does not exist? Or what if you accidentally deleted it when the
  5. program was running? Such situations are handled using *exceptions*.
  6. Similarly, what if your program had some invalid statements? This is handled by Python which
  7. *raises* its hands and tells you there is an *error*.
  8. === Errors
  9. Consider a simple `print` function call. What if we misspelt `print` as `Print`? Note the
  10. capitalization. In this case, Python _raises_ a syntax error.
  11. --------------------------------------------------
  12. >>> Print "Hello World"
  13. File "<stdin>", line 1
  14. Print "Hello World"
  15. ^
  16. SyntaxError: invalid syntax
  17. >>> print "Hello World"
  18. Hello World
  19. --------------------------------------------------
  20. Observe that a `SyntaxError` is raised and also the location where the error was detected is
  21. printed. This is what an *error handler* for this error does.
  22. === Exceptions
  23. We will *try* to read input from the user. Press `ctrl-d` and see what happens.
  24. --------------------------------------------------
  25. >>> s = raw_input('Enter something --> ')
  26. Enter something --> Traceback (most recent call last):
  27. File "<stdin>", line 1, in <module>
  28. EOFError
  29. --------------------------------------------------
  30. Python raises an error called `EOFError` which basically means it found an *end of file* symbol
  31. (which is represented by `ctrl-d`) when it did not expect to see it.
  32. === Handling Exceptions
  33. We can handle exceptions using the `try..except` statement. We basically put our usual statements
  34. within the try-block and put all our error handlers in the except-block.
  35. Example (save as `exceptions_handle.py`):
  36. [source,python]
  37. --------------------------------------------------
  38. include::programs/exceptions_handle.py[]
  39. --------------------------------------------------
  40. Output:
  41. --------------------------------------------------
  42. include::programs/exceptions_handle.txt[]
  43. --------------------------------------------------
  44. .How It Works
  45. We put all the statements that might raise exceptions/errors inside the `try` block and then put
  46. handlers for the appropriate errors/exceptions in the `except` clause/block. The `except` clause
  47. can handle a single specified error or exception, or a parenthesized list of errors/exceptions. If
  48. no names of errors or exceptions are supplied, it will handle _all_ errors and exceptions.
  49. Note that there has to be at least one `except` clause associated with every `try`
  50. clause. Otherwise, what's the point of having a try block?
  51. If any error or exception is not handled, then the default Python handler is called which just
  52. stops the execution of the program and prints an error message. We have already seen this in action
  53. above.
  54. You can also have an `else` clause associated with a `try..except` block. The `else` clause is
  55. executed if no exception occurs.
  56. In the next example, we will also see how to get the exception object so that we can retrieve
  57. additional information.
  58. === Raising Exceptions
  59. You can _raise_ exceptions using the `raise` statement by providing the name of the error/exception
  60. and the exception object that is to be _thrown_.
  61. The error or exception that you can raise should be a class which directly or indirectly must be a
  62. derived class of the `Exception` class.
  63. Example (save as `exceptions_raise.py`):
  64. [source,python]
  65. --------------------------------------------------
  66. include::programs/exceptions_raise.py[]
  67. --------------------------------------------------
  68. Output:
  69. --------------------------------------------------
  70. include::programs/exceptions_raise.txt[]
  71. --------------------------------------------------
  72. .How It Works
  73. Here, we are creating our own exception type. This new exception type is called
  74. `ShortInputException`. It has two fields - `length` which is the length of the given input, and
  75. `atleast` which is the minimum length that the program was expecting.
  76. In the `except` clause, we mention the class of error which will be stored `as` the variable name
  77. to hold the corresponding error/exception object. This is analogous to parameters and arguments in
  78. a function call. Within this particular `except` clause, we use the`length` and `atleast` fields of
  79. the exception object to print an appropriate message to the user.
  80. === Try ... Finally
  81. Suppose you are reading a file in your program. How do you ensure that the file object is closed
  82. properly whether or not an exception was raised? This can be done using the `finally` block.
  83. Save this program as `exceptions_finally.py`:
  84. [source,python]
  85. --------------------------------------------------
  86. include::programs/exceptions_finally.py[]
  87. --------------------------------------------------
  88. Output:
  89. --------------------------------------------------
  90. include::programs/exceptions_finally.txt[]
  91. --------------------------------------------------
  92. .How It Works
  93. We do the usual file-reading stuff, but we have arbitrarily introduced sleeping for 2 seconds after
  94. printing each line using the `time.sleep` function so that the program runs slowly (Python is very
  95. fast by nature). When the program is still running, press `ctrl + c` to interrupt/cancel the
  96. program.
  97. Observe that the `KeyboardInterrupt` exception is thrown and the program quits. However, before the
  98. program exits, the finally clause is executed and the file object is always closed.
  99. Note that we use `sys.stdout.flush()` after `print` so that it prints to the screen immediately.
  100. [[with]]
  101. === The with statement
  102. Acquiring a resource in the `try` block and subsequently releasing the resource in the `finally`
  103. block is a common pattern. Hence, there is also a `with` statement that enables this to be done in
  104. a clean manner:
  105. Save as `exceptions_using_with.py`:
  106. [source,python]
  107. --------------------------------------------------
  108. include::programs/exceptions_using_with.py[]
  109. --------------------------------------------------
  110. .How It Works
  111. The output should be same as the previous example. The difference here is that we are using the
  112. `open` function with the `with` statement - we leave the closing of the file to be done
  113. automatically by `with open`.
  114. What happens behind the scenes is that there is a protocol used by the `with` statement. It fetches
  115. the object returned by the `open` statement, let's call it "thefile" in this case.
  116. It _always_ calls the `thefile.__enter__` function before starting the block of code under it and
  117. _always_ calls `thefile.__exit__` after finishing the block of code.
  118. So the code that we would have written in a `finally` block should be taken care of automatically
  119. by the `__exit__` method. This is what helps us to avoid having to use explicit `try..finally`
  120. statements repeatedly.
  121. More discussion on this topic is beyond scope of this book, so please refer
  122. http://www.python.org/dev/peps/pep-0343/[PEP 343] for a comprehensive explanation.
  123. === Summary
  124. We have discussed the usage of the `try..except` and `try..finally` statements. We have seen how to
  125. create our own exception types and how to raise exceptions as well.
  126. Next, we will explore the Python Standard Library.