1 00:00:00,000 --> 00:00:04,585 [MUSIC] 2 00:00:04,585 --> 00:00:07,646 Welcome back, we've been looking at the tools Python provides for 3 00:00:07,646 --> 00:00:09,670 making our way around file systems. 4 00:00:09,670 --> 00:00:12,500 We're now able to change the directory we're working in, create paths for 5 00:00:12,500 --> 00:00:13,910 the directories and files, and 6 00:00:13,910 --> 00:00:17,300 check the stats of a file to see how big it is and other things. 7 00:00:17,300 --> 00:00:20,250 While all of that's pretty handy, none of that gets us very far if we can't 8 00:00:20,250 --> 00:00:22,880 do things with the files and directories that we find. 9 00:00:22,880 --> 00:00:25,620 This stage won't focus too much on writing to files. 10 00:00:25,620 --> 00:00:28,530 Check the teacher's notes if you want more information on working with files. 11 00:00:28,530 --> 00:00:31,300 Instead, we're going to look at Python's tools for creating files and 12 00:00:31,300 --> 00:00:33,540 directories as a step by itself. 13 00:00:33,540 --> 00:00:37,340 While this will include writing to files, we won't spend a lot of time on that. 14 00:00:37,340 --> 00:00:40,530 Okay, let's go see how we can use Python to create our files and directory trees. 15 00:00:41,960 --> 00:00:43,560 Before we try to make a file or 16 00:00:43,560 --> 00:00:47,480 directory, we should probably make sure that it doesn't already exist, right? 17 00:00:47,480 --> 00:00:50,640 The OS dot path module already has a method for this. 18 00:00:50,640 --> 00:00:54,520 So let's say I wanted to make the bootstrap directory in this workspace so 19 00:00:54,520 --> 00:00:57,800 I've imported the OS, I can do OS dot path dot exists. 20 00:00:58,850 --> 00:01:04,290 And I can search for bootstrap, and I get back true, that it does exist so 21 00:01:04,290 --> 00:01:07,870 great, I know it exists, I can avoid trying to create it again. 22 00:01:07,870 --> 00:01:15,020 And this works for files as well so I can do bootstrap/js/npm.js. 23 00:01:15,020 --> 00:01:16,310 And I get back True. 24 00:01:16,310 --> 00:01:20,570 If I search for say, treehouse.js, I get back False, 25 00:01:20,570 --> 00:01:22,530 because that one does not exist. 26 00:01:22,530 --> 00:01:23,120 So, that's cool. 27 00:01:23,120 --> 00:01:27,560 I can know whether or not a file or directory exists. 28 00:01:27,560 --> 00:01:30,400 And, I can create any that I'm missing. 29 00:01:30,400 --> 00:01:33,120 For creating files, I can of course just use open. 30 00:01:34,190 --> 00:01:38,830 And I can say that I'm going to open, like test_file.txt. 31 00:01:38,830 --> 00:01:42,110 And I can use W, to truncate it or erase it, and 32 00:01:42,110 --> 00:01:46,310 then start writing to it, or I can use A, to append to whatever's there. 33 00:01:46,310 --> 00:01:49,325 And then I can just close the file. 34 00:01:49,325 --> 00:01:51,760 File's been opened, it's been written to, it's been closed. 35 00:01:51,760 --> 00:01:53,980 And that works, but it takes two steps, and 36 00:01:53,980 --> 00:01:56,150 I have to remember to use either W or A. 37 00:01:56,150 --> 00:02:01,910 If I was to try to do, like say, test_file2 and I left off the w. 38 00:02:01,910 --> 00:02:04,690 Then Python will complain at me that that file doesn't exist. 39 00:02:05,930 --> 00:02:13,670 So to avoid doing that, I would love to use the os.mknod method. 40 00:02:13,670 --> 00:02:16,930 But I can't because I'm showing this to you on a Mac. 41 00:02:16,930 --> 00:02:20,560 So normally here I would do bootstrap/js/treehouse.js and 42 00:02:20,560 --> 00:02:23,840 then it would create it. 43 00:02:23,840 --> 00:02:26,925 But if I try and do this I get back permission denied. 44 00:02:26,925 --> 00:02:31,245 And the reason is because on MacOS and MacOS only, for 45 00:02:31,245 --> 00:02:37,285 Python to use the os.mknod [SP] function you have to be running Python as root, 46 00:02:37,285 --> 00:02:40,025 so you would have to have done like sudo python three. 47 00:02:41,075 --> 00:02:43,145 Now, I don't like that. 48 00:02:43,145 --> 00:02:44,985 I don't like that you have to do that, but 49 00:02:44,985 --> 00:02:47,875 I can't change that because I have no control over what Apple does. 50 00:02:47,875 --> 00:02:49,685 So if you're watching this course and 51 00:02:49,685 --> 00:02:54,930 you're on a Mac, don't bother with OS.mknod, you'll have to use the open and 52 00:02:54,930 --> 00:02:58,990 close method, or one of various other methods that you can find by Googling. 53 00:03:00,090 --> 00:03:05,400 If you're on Linux or Windows, the OS.mknod will work just fine. 54 00:03:05,400 --> 00:03:06,500 You can create the files. 55 00:03:06,500 --> 00:03:11,840 And by default it will create a file with the permissions set to 0600. 56 00:03:11,840 --> 00:03:15,020 If you need to know more about modes you can check the teacher's notes for 57 00:03:15,020 --> 00:03:17,090 our console foundations course. 58 00:03:17,090 --> 00:03:19,820 MKnod can be used to make more than just files but 59 00:03:19,820 --> 00:03:22,560 that's way beyond the scope of this course. 60 00:03:22,560 --> 00:03:25,230 As always, check the documentation for more information and examples. 61 00:03:26,280 --> 00:03:32,330 Okay, so, small rant and mknod aside, what about directories? 62 00:03:32,330 --> 00:03:35,310 Well, we have two options for making directories in Python. 63 00:03:35,310 --> 00:03:40,870 If I only want to make one directory I can do that directly with os.mkdir. 64 00:03:40,870 --> 00:03:44,710 So I could just say, make the directory templates and 65 00:03:44,710 --> 00:03:47,170 Python will make this directory. 66 00:03:47,170 --> 00:03:50,180 If I look over here, I can see hey, I have a templates directory and 67 00:03:50,180 --> 00:03:55,550 there's my test file that I created and didn't do anything with. 68 00:03:55,550 --> 00:03:59,450 Using mkdir though would get very annoying if you had to make a deep tree of 69 00:03:59,450 --> 00:04:03,380 directories that all had to be made from the bottom back up. 70 00:04:03,380 --> 00:04:08,730 Or rather, from the top down because you'd have to do it one directory at a time. 71 00:04:08,730 --> 00:04:12,500 Luckily there is the makedirs function. 72 00:04:12,500 --> 00:04:15,900 And this one will create them all the way down. 73 00:04:15,900 --> 00:04:18,570 First though, I wanna delete this templates directory so 74 00:04:18,570 --> 00:04:24,720 I'm gonna delete that, and then I'm gonna make, templates, layouts, and mobile. 75 00:04:24,720 --> 00:04:27,990 So you can see, I have three directories there, the templates directory and 76 00:04:27,990 --> 00:04:29,660 inside of that it's gonna be the layouts directory, and 77 00:04:29,660 --> 00:04:31,610 inside of that will be the mobile directory. 78 00:04:32,760 --> 00:04:36,450 So now if I come over and I check, I have templates, I have layouts and 79 00:04:36,450 --> 00:04:37,430 I have mobile. 80 00:04:37,430 --> 00:04:38,270 And on the inside of mobile, 81 00:04:38,270 --> 00:04:41,570 there's nothing because I haven't put anything there. 82 00:04:41,570 --> 00:04:45,090 Makedirs has an extra argument though that I think you should know about. 83 00:04:45,090 --> 00:04:48,300 Let's try running the command again, exactly as we just ran it. 84 00:04:48,300 --> 00:04:53,450 And you can see we get back this new error which is the FileExistsError. 85 00:04:53,450 --> 00:04:55,400 And it says that this directory already exists. 86 00:04:55,400 --> 00:04:57,380 It's kind of funny that it's called FileExists 87 00:04:57,380 --> 00:04:58,730 when it's a directory, but that's fine. 88 00:04:59,860 --> 00:05:00,790 If the target directory, 89 00:05:00,790 --> 00:05:03,440 the one at the end, already exists, you're gonna get this error. 90 00:05:04,540 --> 00:05:05,970 If that matters to you, great. 91 00:05:05,970 --> 00:05:08,240 Catch the error, do whatever you need to do there. 92 00:05:08,240 --> 00:05:10,420 Tell the user that the directory already exists and 93 00:05:10,420 --> 00:05:12,436 you can't make a new one or whatever. 94 00:05:12,436 --> 00:05:16,690 If it doesn't though, if it doesn't matter to you that the directory exists, 95 00:05:16,690 --> 00:05:20,640 you can tell Python that it's okay if the directory exists. 96 00:05:20,640 --> 00:05:23,480 So let me clear the screen here and we'll run this again. 97 00:05:23,480 --> 00:05:29,760 And this time we will say, exist_ok=True and Python doesn't complain at us. 98 00:05:29,760 --> 00:05:32,600 Python goes you don't care if the directory exists? 99 00:05:32,600 --> 00:05:34,940 The directory exists, we're just gonna move on. 100 00:05:34,940 --> 00:05:38,559 I've found that most of the time, this is the behavior that I actually want. 101 00:05:38,559 --> 00:05:43,350 There are two things on every function we've used that's handy to know. 102 00:05:43,350 --> 00:05:45,810 First, all of these paths we've been providing are relative, but 103 00:05:45,810 --> 00:05:47,730 you can provide absolute paths, too. 104 00:05:47,730 --> 00:05:48,745 The functions will still work the same way. 105 00:05:48,745 --> 00:05:51,053 They'll just go to the absolute location you provided, 106 00:05:51,053 --> 00:05:54,540 instead of going forward from the current working directory. 107 00:05:54,540 --> 00:05:58,570 Second, you can create a path-like object, like you'd get from pathlib, and 108 00:05:58,570 --> 00:06:01,210 provide that instead of providing a path as a string. 109 00:06:01,210 --> 00:06:04,810 It's often much handier when working with paths that are generated by your software 110 00:06:04,810 --> 00:06:07,750 or from user input instead of paths that you're typing directly into your code.