python-crash-course-book/chap10_file_exceptions.md

121 lines
3.1 KiB
Markdown
Raw Normal View History

2020-09-08 17:17:39 +10:00
# Chapter 10. Files and Exceptions
Files operation skipped here. Directly head to Exception
## Exceptions
* **exceptions** = objects python use to manage errors that arise during a program's execution.
* When python unsure what to do, exception object is created.
* If exceptions are handled correctly, program can continue run
* If don't handle exception, program will halt and show *traceback*
Syntax of exception handling: `try-except`
* `try` tells python do sth
* `except` tell python what to do if an exception is raised.
### e.g. ZeroDivisionError Exception
* Simple error, python will create `ZeroDivisionError` in response to do "Divide by Zero".
* When you think an error may occur, you can write a `try-except` block to handle exception
```python
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
```
If more code followed `try-except` block, the program would continue running. e.g. as shown below
### Using Exceptions to Prevent Crashes
Handling errors correctly is important when the program has more work to do after the error occurs.
```python
print("Give me two numbers, and I'll divide them.")
print("Enter 'q' to quit.")
while True:
first_number = input("\nFirst number: ")
if first_number == 'q':
break
second_number = input("Second number: ")
if second_number == 'q':
break
answer = int(first_number) / int(second_number)
print(answer)
```
This function ask for numbers and will calculate division. To properly cover potential failure, use `try-except-else` block
* `try` block: Python attempts to run code
* `except` block: catch possible error
* `else` block: if division operation is successful, carry on!
Hence, program can be more robust
```python
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)
```
### Handling FileNotFoundError Exception
```python
filename = 'alice.txt'
with open(filename, encoding='utf-8') as f:
contents = f.read()
```
If python cannot find `alice.txt`, it will raise halt, and show traceback
```
Traceback (most recent call last):
File "alice.py", line 6, in <module>
with open(filename, encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'
```
After changing python code to
```python
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist")
```
Python will show "Sorry, the file alice.txt does not exist"
### Failing Silently
If you want the program to fail silently and carry on, use `pass` to tell Python to do nothing, and skip the try-except-else blocks
```python
def count_words(filename):
"""Count the approximate number of words in a file."""
try:
--snip--
except FileNotFoundError:
pass
else:
--snip--
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
count_words(filename)
```
## Storing Data
`json.dump()` & `json.load`