1 00:00:01,150 --> 00:00:01,983 - [Instructor] In this video, 2 00:00:01,983 --> 00:00:04,360 I'd like to talk about the finally clause 3 00:00:04,360 --> 00:00:05,820 of a try statement. 4 00:00:05,820 --> 00:00:09,770 Now the finally clause, is guaranteed to execute 5 00:00:09,770 --> 00:00:13,880 if the normal flow of control of your Python code 6 00:00:13,880 --> 00:00:17,340 enters a try statements suite. 7 00:00:17,340 --> 00:00:20,091 So if I go into the try statement and start executing, 8 00:00:20,091 --> 00:00:23,610 and the try statement has a finally clause at the end, 9 00:00:23,610 --> 00:00:26,410 that finally clause is guaranteed to execute 10 00:00:26,410 --> 00:00:28,570 with the only exception to that being, 11 00:00:28,570 --> 00:00:30,930 if you manually terminate the code 12 00:00:30,930 --> 00:00:34,060 by calling system.exit for example. 13 00:00:34,060 --> 00:00:36,380 Now, if you're coming into Python 14 00:00:36,380 --> 00:00:38,880 from a language like C# or Java 15 00:00:38,880 --> 00:00:41,460 that has a finally clause on the try statement, 16 00:00:41,460 --> 00:00:43,900 you're already familiar with the basic concept. 17 00:00:43,900 --> 00:00:45,990 If you're not, the idea is 18 00:00:45,990 --> 00:00:50,160 that in a try statement, you might acquire a resource 19 00:00:50,160 --> 00:00:53,010 and then you want to use that resource 20 00:00:53,010 --> 00:00:56,070 and maybe an exception could occur 21 00:00:56,070 --> 00:00:58,060 if you're working with that resource 22 00:00:58,060 --> 00:01:00,660 and sometimes it will and sometimes it won't, 23 00:01:00,660 --> 00:01:02,880 but you want to absolutely guarantee 24 00:01:02,880 --> 00:01:05,700 that you give that resource back to the system 25 00:01:05,700 --> 00:01:07,702 before the try system terminates, 26 00:01:07,702 --> 00:01:10,670 so resource deallocation code 27 00:01:10,670 --> 00:01:14,440 would typically be placed in a finally block or suite 28 00:01:14,440 --> 00:01:16,350 as we call it in Python. 29 00:01:16,350 --> 00:01:20,300 Now in Python, those types of resources 30 00:01:20,300 --> 00:01:23,830 are typically acquired in with statements 31 00:01:23,830 --> 00:01:27,590 like we demonstrated with files earlier in this lesson, 32 00:01:27,590 --> 00:01:29,840 and with statements automatically 33 00:01:29,840 --> 00:01:32,560 give those resources back to the system. 34 00:01:32,560 --> 00:01:35,500 So there's less need for a finally block, 35 00:01:35,500 --> 00:01:38,410 unless you're dealing with some sort of resource, 36 00:01:38,410 --> 00:01:41,430 that does not have that automated support 37 00:01:41,430 --> 00:01:44,440 for working in a with statement. 38 00:01:44,440 --> 00:01:46,110 So it's there in case you need it, 39 00:01:46,110 --> 00:01:47,930 but in the vast majority of cases 40 00:01:47,930 --> 00:01:49,800 for those types of resources, 41 00:01:49,800 --> 00:01:52,970 we'd use with statements in Python. 42 00:01:52,970 --> 00:01:57,760 But let's go ahead and demonstrate the basic finally block 43 00:01:57,760 --> 00:02:01,180 and we'll use a mechanical example for this purpose. 44 00:02:01,180 --> 00:02:03,680 Here I've pasted in a try statement. 45 00:02:03,680 --> 00:02:07,230 In the try suite, we have just a print statement 46 00:02:07,230 --> 00:02:10,960 that will print out try suite with no exceptions raised 47 00:02:10,960 --> 00:02:14,340 and you can see I am not doing something 48 00:02:14,340 --> 00:02:16,170 that would cause an exception here. 49 00:02:16,170 --> 00:02:19,150 I'm not, for example, converting the string hello 50 00:02:19,150 --> 00:02:21,400 to an integer which cannot happen 51 00:02:21,400 --> 00:02:23,380 and therefore would cause an exception. 52 00:02:23,380 --> 00:02:27,040 I'm not using the raise function that's built into Python 53 00:02:27,040 --> 00:02:29,626 to manually cause an exception either, 54 00:02:29,626 --> 00:02:33,520 so the try block will execute successfully here, 55 00:02:33,520 --> 00:02:36,610 which means the except clause will be ignored. 56 00:02:36,610 --> 00:02:39,486 So this will not execute, will not get printed. 57 00:02:39,486 --> 00:02:42,210 The else cause will execute 58 00:02:42,210 --> 00:02:45,410 because as long as no exceptions occur in the try block, 59 00:02:45,410 --> 00:02:47,040 the else clause will execute. 60 00:02:47,040 --> 00:02:50,570 So else executes because no exceptions in the try suite 61 00:02:50,570 --> 00:02:55,250 that will be printed, and because we executed the try suite, 62 00:02:55,250 --> 00:02:59,080 the finally block or the finally suite will also execute 63 00:02:59,080 --> 00:03:01,870 printing finally always executes. 64 00:03:01,870 --> 00:03:04,860 So we should see the first print statements output, 65 00:03:04,860 --> 00:03:06,640 the third print statements output 66 00:03:06,640 --> 00:03:10,500 and the finally print statements output as well 67 00:03:10,500 --> 00:03:12,640 and if you check these, you'll see that 68 00:03:12,640 --> 00:03:16,240 that is indeed the case in this example. 69 00:03:16,240 --> 00:03:19,421 Now let's once again, take a look at a try statement 70 00:03:19,421 --> 00:03:22,350 this time for a try suite 71 00:03:22,350 --> 00:03:25,460 in which an exception actually does occur. 72 00:03:25,460 --> 00:03:28,870 So here I've pasted in another try statement. 73 00:03:28,870 --> 00:03:31,550 In this try statement, we will print try statement 74 00:03:31,550 --> 00:03:33,160 that raises an exception, 75 00:03:33,160 --> 00:03:37,240 and then we will attempt to call the built in function int 76 00:03:37,240 --> 00:03:39,910 to convert the string hello to an integer. 77 00:03:39,910 --> 00:03:41,500 Now of course the string hello 78 00:03:41,500 --> 00:03:45,610 is not a valid integer representation as a string 79 00:03:45,610 --> 00:03:48,890 and therefore this will cause a value error. 80 00:03:48,890 --> 00:03:52,160 Now the try suite will terminate at this point, 81 00:03:52,160 --> 00:03:55,210 which is known as the raise point of the exception 82 00:03:55,210 --> 00:03:56,300 that occurs. 83 00:03:56,300 --> 00:04:00,460 Any statements that follow the highlighted statement here 84 00:04:00,460 --> 00:04:03,610 will not execute when that exception occurs 85 00:04:03,610 --> 00:04:06,150 and flow of control will continue 86 00:04:06,150 --> 00:04:08,850 with the except clause for the value error. 87 00:04:08,850 --> 00:04:13,850 So we will print out try suite that raises an exception, 88 00:04:14,030 --> 00:04:15,770 then we will jump down here 89 00:04:15,770 --> 00:04:18,610 and print out a value error occurred 90 00:04:18,610 --> 00:04:20,170 because an exception occurred, 91 00:04:20,170 --> 00:04:23,170 the else suite will be ignored, 92 00:04:23,170 --> 00:04:26,120 but the finally suite always executes. 93 00:04:26,120 --> 00:04:28,220 So in this case, we expect 94 00:04:28,220 --> 00:04:30,610 to see the first print statement execute, 95 00:04:30,610 --> 00:04:33,950 the except clauses print statement execute, 96 00:04:33,950 --> 00:04:37,250 and the finally clauses print statement execute 97 00:04:37,250 --> 00:04:40,990 and as you can see here, those are the three prints 98 00:04:40,990 --> 00:04:43,540 that we did indeed get. 99 00:04:43,540 --> 00:04:46,110 Now going back to what I said earlier 100 00:04:46,110 --> 00:04:48,720 about this issue that in Python, 101 00:04:48,720 --> 00:04:52,010 most resources that need to be deallocated 102 00:04:52,010 --> 00:04:56,700 when you're done using them will work with a with statement. 103 00:04:56,700 --> 00:04:59,560 So it's not uncommon if you're trying 104 00:04:59,560 --> 00:05:02,140 to deal with exceptions that might occur 105 00:05:02,140 --> 00:05:05,610 from those resources like working with a file on disk 106 00:05:05,610 --> 00:05:10,280 to wrap a with statement in a try statement. 107 00:05:10,280 --> 00:05:14,410 So let me first demonstrate an exception that occurs 108 00:05:14,410 --> 00:05:18,040 if we try to open a file that does not exist. 109 00:05:18,040 --> 00:05:21,100 So first thing I'm gonna do here is just clear my screen 110 00:05:21,100 --> 00:05:23,300 so that I can get back to the top here 111 00:05:23,300 --> 00:05:27,500 and let's say we want to open a file that does not exist 112 00:05:27,500 --> 00:05:28,520 in my system. 113 00:05:28,520 --> 00:05:31,420 I misspelled grades here on purpose. 114 00:05:31,420 --> 00:05:33,390 In that case, I get an exception. 115 00:05:33,390 --> 00:05:37,320 A file not found error indicating that a problem occurred. 116 00:05:37,320 --> 00:05:40,062 Now normally I would not execute this function call 117 00:05:40,062 --> 00:05:42,640 in a snippet by itself, 118 00:05:42,640 --> 00:05:45,730 instead I would probably have that in a with statement 119 00:05:45,730 --> 00:05:47,750 that says go ahead and open that, 120 00:05:47,750 --> 00:05:51,030 assign the open file to a particular variable name 121 00:05:51,030 --> 00:05:54,880 and then process the data in that file in some way. 122 00:05:54,880 --> 00:05:57,150 So let's take a look at what you might do 123 00:05:57,150 --> 00:06:00,950 to combine a with statement with a try statement. 124 00:06:00,950 --> 00:06:02,750 So here we have a try statement 125 00:06:02,750 --> 00:06:04,050 that's going to attempt 126 00:06:04,050 --> 00:06:08,030 to open the gradez.txt file for reading. 127 00:06:08,030 --> 00:06:09,572 This file does not exist. 128 00:06:09,572 --> 00:06:12,330 If it does get opened, it would be assigned 129 00:06:12,330 --> 00:06:14,160 to the variable accounts 130 00:06:14,160 --> 00:06:16,078 and then we would do some processing 131 00:06:16,078 --> 00:06:19,510 of that file of information. 132 00:06:19,510 --> 00:06:22,120 Now in this case, the file does not exist, 133 00:06:22,120 --> 00:06:25,102 so because of the fact that we've put the with statement 134 00:06:25,102 --> 00:06:29,410 in the try suite, we can look for 135 00:06:29,410 --> 00:06:31,420 and deal with that exception. 136 00:06:31,420 --> 00:06:35,040 So if the exception occurs, the except clause 137 00:06:35,040 --> 00:06:38,630 for the file not found error will match the exception 138 00:06:38,630 --> 00:06:40,890 that occurred when we tried to call open 139 00:06:40,890 --> 00:06:42,040 and we will print 140 00:06:42,040 --> 00:06:44,930 the file name you specified does not exist. 141 00:06:44,930 --> 00:06:48,090 So let me go ahead and execute that snippet, 142 00:06:48,090 --> 00:06:52,470 and indeed our print statement in the except clause executes 143 00:06:52,470 --> 00:06:53,830 rather than us displaying 144 00:06:53,830 --> 00:06:56,039 this ugly file not found error trace back 145 00:06:56,039 --> 00:06:58,880 that we saw back in snippet four. 146 00:06:58,880 --> 00:07:01,810 So of course if we're creating larger applications 147 00:07:01,810 --> 00:07:04,910 and scripts that other people are going to execute, 148 00:07:04,910 --> 00:07:06,920 we're probably going to want 149 00:07:06,920 --> 00:07:09,260 to use some more exception handling 150 00:07:09,260 --> 00:07:12,120 to make it a little bit nicer 151 00:07:12,120 --> 00:07:16,133 for the user interacting with that application or script.