Python Tutorial: Clarifying the Issues with Mutable Default Arguments
16:04

Python Tutorial: Clarifying the Issues with Mutable Default Arguments

Corey Schafer 24.04.2019 37 988 просмотров 1 463 лайков

Machine-readable: Markdown · JSON API · Site index

Поделиться Telegram VK Бот
Транскрипт Скачать .md
Анализ с AI
Описание видео
In this Python Programming Tutorial, we will be clarifying the issues with mutable default arguments. We discussed this in my last video titled "5 Common Python Mistakes and How to Fix Them", but I received many comments from people who were still confused. So we will be doing a deeper dive to explain exactly what is going on here. Let's get started... 5 Common Python Mistakes - https://youtu.be/zdJEYhA2AZQ ✅ Support My Channel Through Patreon: https://www.patreon.com/coreyms ✅ Become a Channel Member: https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join ✅ One-Time Contribution Through PayPal: https://goo.gl/649HFY ✅ Cryptocurrency Donations: Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3 Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33 Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot ✅ Corey's Public Amazon Wishlist http://a.co/inIyro1 ✅ Equipment I Use and Books I Recommend: https://www.amazon.com/shop/coreyschafer ▶️ You Can Find Me On: My Website - http://coreyms.com/ My Second Channel - https://www.youtube.com/c/coreymschafer Facebook - https://www.facebook.com/CoreyMSchafer Twitter - https://twitter.com/CoreyMSchafer Instagram - https://www.instagram.com/coreymschafer/ #Python

Оглавление (3 сегментов)

Introduction

hey there how's it going everybody so I wanted to do a quick follow-up video to my last video on five common python mistakes and explain one of those mistakes in a bit more detail so one of the things that I talked about in that video was mutable default arguments and the issues that you can run into when using those and it seems like there were still a lot of people confused by how those work and after going back and watching that video again I realized that I could have added in some extra details that would have made that a lot easier to understand so I wanted to make a quick follow-up video and try to make sure uh that that's a bit more clear as to what's going on there so I have my example from that last video open and in case you missed that video let me go over the problem one more time uh so we have a function here called add employee uh so let me explain what this function is meant to do so it takes a single employee as its first argument and also a list of employees here called employee list and then it's simply going to append uh this employee that we pass in to that list and then print out that employee list so we can see here that the employee list has a default argument set to an empty list uh and an empty list is a mutable data type so what we want to happen here is if we don't pass in an employee list to the function then it should just create a new one from scratch for us but let's actually see what this does so I have an existing list of employees down here uh so let me add a new employee and I'm going to use that function uh to add an employee to that list so I'll just add an employee of Corey I'm going to pass in that existing list that we want to append to and now it should print out that employee list so if I run that then we can see that works fine uh our employee was added to that employee list but now let's add a couple of employees without providing an existing list so I will add Corey here and I'll also add an employee of John so if I save that and run it then what we're going to expect happens here is that since we're not passing in a default or a list here it's going to use the default of an empty list and just add that one employee to that empty list and the second time through we would expect that John will also get added to an empty list since that's the default and we didn't provide an existing list here but if I save that and run it then we can see that it seems like it used that same list twice and it added JN on here uh to this list that was created here which is kind of strange and if we keep doing this then it's just going to keep adding to that list so that's a bit weird because we expect it to be setting this to an empty list each time we run the function so what's going on here is that in Python default arguments are evaluated once at the time it creates the function so it's not actually creating a new list each time we run the function now you won't notice this with immutable types like strings and things like that but with mutable data types like a list uh it's going to use that same list that it created when the function was defined so in the last video that's about as much detail as I went into uh I then showed that in order to fix the problem we would just need to set the default argument to none and then set the empty list inside the function so let me do that again but this time I'm going to create that function separately so that we can compare these so I'm just going to copy this function here and I'm going to create a new one and I'm going to call this add employee fixed and to in order to fix this function like I was saying we can just set the default argument To None oops that's none and then inside here I will say if the employee list is none then we want to set employee list equal to an empty list so again in the original video that's about as much detail as I went into but there were still some people confused by this I had a few people who commented who said well if the default arguments are only set once when the function is created uh then how is the employee list set To None uh each time we run the function so here's where I feel like I failed to provide a proper explanation so I never said that the default arguments were only set one time when the function is created uh I said that the default arguments were only evaluated one time each time the function is created so to illustrate this more clearly we can look at a magic method on our function that holds the default arguments and I think that's going to make things a lot more clear as to what's going on here so first let me show this on our original function up here so I'm going to uh copy our output here and paste it in and let me actually just um comment those out uh and I'm going to comment these out now uh for now as well so right underneath this function here I'm going to print out add employee and this has a magic method here called defaults so and this isn't actually a method sorry it is uh an attribute so I don't want to put parentheses there to run it so if I save

Understanding Mutable Defaults

this and I run it then these are the defaults that were created for this function and this is what only gets evaluated once so we can see that this has a default of an empty list but a list is mutable so since this was only created once and set as a default here uh we can actually add to this list and each time we run the function if we don't provide anything for our employee list then it's going to set it equal to this default value here but let me show you what happens when we add an employee so let me add an employee and then I'll print out that default again so if I save this and I run it then we can see that the first time through it evaluated that empty list once so it says okay I have a default value here that is an empty list then we added this employee and it appended it to that default list and then we're printing the list here so we have a list of one person and now when we print those defaults afterwards that original list that it created uh now has a value it has a value of Corey so it's no longer empty because it only creates that empty list that one time and now we're mutating that list since lists are mutable so now every time through uh if I look at this and I keep adding employees then every time through it started out as empty then we added Corey and now Corey is that default list then we added John and now we have Cory and John as that default list so that's why that keeps getting modified each time uh we run that function so now let me show you this with our fixed version where we set this equal to none um so right underneath here I'm going to print out and I'm just going to get rid of this list here I don't need that anymore um so now I'm just going to print out add employee fixed do defaults and let's look at this so now when I run this we can see that we have a default value of none so that got evaluated once but just because it got evaluated once doesn't mean that it doesn't get set to that value each time we run the function if an argument isn't uh supplied it'll still set each time equal to that default value but it's only evaluated one time and if this still doesn't make sense then I think it'll really knock at home once we look at the date time example down here at the bottom uh but for now let's just stick with this example so now I'm going to uncommon out adding one employee here and then I'm going to uh print out the defaults after we add that employee let me make this a little smaller here so that we can see a little bit more of the code here so now I'm going to save this and run it and we can see that the first time through it evaluated this statement one time of employee the default of employee list is equal to none so that was our default and we can see that here so then we added an employee and it came up here and it said okay uh so we don't have an employee list that we want to append to so this is equal to none uh so by default it sets that equal to none then we come in here in the function and it says okay if employee list is equal to none which it is because that's our default then just create a new empty list and then we appin to that list and print out those employees so we printed out our one employee that was added to this empty list here and now when we print out the defaults again afterwards that default is still equal to none because it's it even though it was evaluated one time uh that's not mutable so that's not getting changed each time through like our list was so we can come in here and when we're adding more and more employees so I can add John and save that and run it whoops and it looks like uh that's a mistake but it's not it's because I'm using add employee instead of add employee fixed here um so let me put in add employee fix there so now when we run this now we can see that uh it's not appending to that list every time because um this since this is set to none as the default it is still setting employee list to that default value every time we run the function but the difference between our fixed function and our other function was that when it sets it to none is not being modified each time through uh but this mutable default argument that's the reason that these are a problem that was getting modified each time through so when I say that those default arguments are evaluated one time every uh when the function is created I don't mean that it only sets that value one time this is still getting set to this list each time we don't provide a list and this is still getting set To None each time we uh don't provide the employee list uh but it's just the initial values is what gets evaluated once so I really think this point will be knocked home uh once we look at this datetime example down here um so let me show you this example

Example

here and I showed this in the original video as well so we have a function here called display time and it takes in time as an argument and then it's just going to print that out in a special format uh now if we don't provide a time then this has a default argument of datetime do now this isn't exactly the same as mutable default arguments like we were talking about before but we can still see why this would be a problem if we think about it uh because this gets evaluated one time and gets set to those default fults so if you didn't know that then what you might expect to happen here is each time we run this function and we don't provide a date then we would think that it would just use this default value here of datetime. now and that would be executed each time we run the function so down here I'm running display time uh three different times but I'm sleeping a second between each time I call that function so we might expect that since it's using uh now that it would increment by a second each time through but if I run this then we can see that it does wait a second each time through but it's not incrementing by a second so it's just printing out the same time over and over so why is it doing this the reason it's doing this let me print out display time uh and then I will print out those defaults oops and that's a uh magic or a Dunder attribute there uh so I want to be sure I have those and now let me uh actually I'll keep those in as well um so if I run this now where I'm printing out those defaults uh if I run that then we can see that the default value it executed this uh datetime. now and set it here in our defaults so this is what's going to get uh this is the default value that it's going to be set to every time we run the function so and we can see here that it's 10 seconds into the minute and that's what gets run every time we run display time it gets set there and even though we're sleeping it's still the same default value here uh so that was evaluated once and now that is our default value it's not uh being set to the actual dot now each time the function is executed it's being set to this default here so that's probably not what you would expect to happen if you didn't know about this so again the fix for this uh like we saw like I showed in the last video in the common mistakes video is to just set that equal to none and now we'll say if the time to print is none then we want to uh set the time to print equal to datetime dot now oops sorry date time. now so now when we run this I can see here that our default value is equal to none uh so it's not evaluating that date time. now uh that one time when we create the function so it comes in here and it says okay I'm running display time they didn't provide me a time to print out so I'm going to set this equal to none so if time to print is none which it is each time through then we want the time to print to be equal to datetime. now now this does get executed each time we run the function uh because it's coming in here and running this code every time we run the function so now we can see that our seconds are being updated like we would expect uh because it's sleeping for 1 second in between those function calls okay so now let me close this and uh just scroll up here a little bit okay so that's all I wanted to show in this video just a quick little update uh to that last video I put out I hope that this was a lot more clear this time around when I actually showed this defaults value here and how that gets evaluated once but uh the general confusion seemed to be that people were wondering like okay well if it's evaluated once they seem to think that it meant that it was only set one time and that it didn't set these default values each time you run the function it does but if you use something that is executed or a mutable default argument then that's where you run into problems like we saw in this video so I hope that this video cleared up any confusion that may be lingering after that last video where I didn't go into as much detail uh but if you do have any further questions then feel free to ask in the comment section below and I'll do my best to answer those and if you enjoy these tutorials and would like to support them then there are several ways you can do that the easiest way is to Simply like the video and give it a thumbs up and also it's a huge help to share these videos with anyone who you think would find them useful and if you have the means you can contribute through patreon and there's a link to that page in the description section below be sure to subscribe for future videos and thank you all for watching

Другие видео автора — Corey Schafer

Ctrl+V

Экстракт Знаний в Telegram

Экстракты и дистилляты из лучших YouTube-каналов — сразу после публикации.

Подписаться

Дайджест Экстрактов

Лучшие методички за неделю — каждый понедельник