5 Python BAD Practices To Avoid

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everybody and welcome back so in today's video i'm going to be showing you five python bad practices that you should avoid now these are things that many people do not actually know are bad practices they seem normal or kind of usual or natural to do but can lead to a lot of complications errors or just messy and unreadable code so with that said let's go ahead and dive into the video after a quick word from our sponsor before we get started i need to thank vidyard for sponsoring this video vidyard provides video tools built for improving communication and making remote work easier vidyard's video creation tools let you create and stream videos seamlessly so that you can better communicate with your employees or co-workers vidyard provides a free chrome extension and a desktop application that lets you record your audio video screen and all combinations of the above you can also upload existing videos to vidyard a great feature of vidyard is once you stop your recording it's automatically uploaded to vidyard so you can attach an email slack channel or wherever else you'd like to share it vidyard can be used to quickly log a bug while providing a demo ask detailed questions about code and to get feedback quicker from your team vidyard is perfect for senior leaders employee communication and for creating training in hr videos not only do vidyard videos add a personal touch to communication but they also have detailed analytics and security settings so you can track engagement and limit access to sensitive content vidyard is also used for sas sales and marketing and has all kinds of solutions for any use case vidyard is used by microsoft shopify linkedin and thousands of other large companies and you can get started with it yourself for free today by clicking the link in the description all right so let's move on to our first python bad practice which is mutable default parameters so this bad practice involves using a mutable object as the default parameter for a parameter inside of a function or a method now before i go any further with the explanation just have a look at this code and take a guess at what you think the output is going to be so pause the video if you need to i'm going to explain it now so i'm assuming that most of you would guess that what the output of this should be is one and then inside of a list one and then two and inside of a list two now this is actually not what the output is but intuitively that's kind of what it looks like right so let me stop here and run the code and show you what the output actually is so the output is one inside of a list one two inside of a list one comma two so that's a little bit strange why are we getting one comma 2 as the second result here well the reason why we're getting that is because we're using a mutable default parameter so if this was not a mutable object or this operated in the way that we thought it should operate then what would happen is when we call this function a new empty list would be created and stored in the parameter numbers we would append the number that we passed here to that list we then print the number print that list and then return it but since this is a mutable object this is not being recreated every time we call this function and so on the first function call we have this list object and on the sec second function called surrey numbers is equal to the same list object but now we've appended a 1 into it and so numbers kind of looks like that so we're actually modifying the same object in both of these function calls and i'll just do it one more time to show you that if i do another function call oops meant to run the code here we get the exact same thing right three and then one two three the same pattern persists so these are the exact same objects so we're modifying in every single one of these function calls now just to prove this to you i'm going to show you that the return value which is this list here is the exact same for x y and z they are actually the exact same object so x is y and y is z so when you use is this tells you if two objects are identical if you're the same object and so assuming that x y and z are all the same object this should print true so let's run this and we see that it is indeed true so why is this the case well when you use a mutable value for the default parameter what happens is this parameter here points to kind of a little box in memory that stores this object and it keeps pointing to that box even when you call the function again and again so when i modify what's in that box in memory and i add a 1 to it and then i add a 2 to it it stays the same as the code runs these don't get removed and so that's why we're getting 1 2 1 2 3. hopefully that kind of makes sense but let me show you that the same problem does not occur if we have a non-immutable value here so let's make a string and let's just call this hello and rather than number let's just change this to i know s which will be some string and if i go and do something like okay i need to kind of change the entire thing here let's go s string let's go string plus equals s like that and then print s and print string and then return string and we might as well call this uh append string okay so let's change our example here let's go append underscore string hello or let's just go h oops and then append underscore string i okay so now if i run this code you're gonna see this works in the way that we think it should work so we get hello h and then hello i and that's because this is not a mutable object and that means we cannot modify this object in place so when i do string plus equals s what happens is a brand new string is created and assigned to the value string we print out that value string which is local to this function and then we return that new string object we don't modify what is being stored inside of this string parameter right here and so when we call the function again and string is equal to hello it's still equal to hello it's not been changed because of the fact that this created a brand new string and assigned it to the local variable string which is inside of this function it's a little bit confusing but just understand that you should not use a mutable default parameter for the reason that i just showed you you'll get all kinds of weird results and it's a very difficult thing to debug so moving on to the second bad practice we have not using a default dictionary now explain what that is in one second but first let's have a look at this code right here so we have this dictionary called counts we have a list of numbers we're looping through all of the numbers checking if the number that we're on is in our counts data structure in our dictionary if it's not then we create a new key with that value we set it equal to zero and then we append the value of that key what this is doing is just counting the frequency of all these numbers in the list pretty straight forward now this code is fine you can write this but technically this is considered a bad practice in python because there exists a data structure called a default dictionary which makes it so you do not need to do this check right here and that's kind of the more pythonic way or style of doing this so let me show that to you so to use the default dictionary you need to import it from a built-in module in python called collections so you need to say from collections and then instead of order dick you are going to import the default dictionary like that all right so from collections import default dictionary now to create a default dictionary what you need to do is use the default dict right here so you're going to say counts is equal to default dict and then you need to pass a callable object that returns what the default value for this dictionary should be so i'll kind of explain this in one second but let me just write this out so lambda and then 0 like that now if you're unfamiliar with the lambda this is completely equivalent to this so to find func return zero it's just kind of a shorthand way of doing this this is known as a one line anonymous function anyways what this is saying is if you try to access a key that does not exist in the dictionary it will automatically create one for you that has the value zero that's all it said so let me now show you how we can rewrite this here using the default dictionary so let me copy numbers here and let's say four key in numbers and now what i'm going to do is just say counts which that should be counts at key plus equals one and i'm going to print out counts like that so now if i run this code you're going to see everything works totally fine we don't get any errors this is just functioning properly and the reason for that is we're now using a default dictionary now you will notice that there is some minor differences between a regular dictionary and a default dictionary so you have to be a little bit careful when you're using a default dictionary because some of the methods might be a little bit different but the way you use it is practically the exact same but notice when i print out default dictionary it's giving me the default value and then it's giving me the dictionary it's not just giving me the dictionary so be careful in how you use it you will have to kind of look it up a little bit but it's not very complicated and it saves you you know some cleanliness and readability of your code if you do decide to use it now in the same way here there is another thing that you can use to avoid having to do this type of check when you're kind of trying to access a key or change a key value in dictionary let me just get rid of this example here and show you an example in which what i'm about to show you makes sense so let's say you have a dictionary let's just make it an empty dictionary called d and let's see if a key is in this dictionary so if list is not in d then what i want to do is go d list is equal to that and then i want to say d and sorry this should be at the key list dot append and i want to add maybe the value three into this list the list that's stored as the the value for the key list all right so the way that you can actually shorten these three lines of code right here into one single line is by doing the following without creating a default dictionary you can do this you can say d dot set default you can pass the key value you can pass what the default should be and then you can perform whatever operation you want to perform on this value so i can say dot append and then 3. now what set default does is it will set the default value for a key that you are trying to access if it doesn't exist and then return it but if the key does exist it will return its value so in this case what will happen is if the key list exists in the dictionary it will return the value of that key and then it would append three to it before it returns that story but if it doesn't exist it sets it equal to an empty list and then in this case it's appending three to that list so that is how you can avoid doing this kind of tedious check yours by using this set default method i know myself i didn't know this existed until probably a few months ago actually and it's not something that i used a lot in my python code but definitely saves a bit of time makes your code more readable and is a better practice doing something like this is kind of considered a bad python practice just because again it's not in that pythonic style if you have a method like this you might as well use it so now we're moving on to the next bad practice which is not using a context manager when opening files now in this case when i say context manager i'm referring to the with statement some of you may know what i'm talking about here but let me just show you an example of what the bad practice is and then how to fix it so if you want to work with a file specifically or really any resource that kind of needs cleaning up or closing when you're done working with it you really should use a context manager however not using a context manager would look something like this f equals open file.txt and then we're going to open it in write mode so let's say we want to open this new file called file.txt maybe we want to write some lines to it so f dot write i don't know let's write hello into it or something like that well what we need to do after we've opened this file and we've written lines into it is we need to make sure we close the file so we do something like f dot close now this is fine this code will work all right there won't be any issues here however we really need to make sure whenever we open a file that we close it so if you forget to write this close here that's going to lead to some problems for you i actually don't think this file will save or at least other programs won't be able to access this file this program that's currently running will be kind of the owner and have access to that file and there's just all kinds of issues that can occur if you forget to close a file after you open it so that's a really big deal so okay you might be saying all right i'll just remember to close the file well that's great if you do remember to close the file but another issue can happen if in between when you open the file and you close the file some type of error occurs or your program crashes or the user ends your program before you've closed the file so what you need to do when you're working with files is rather than doing it in this way and just praying that you're actually going to be able to close the file after is you need to use a context manager now a context manager is with and i'll explain kind of what that is but the way that this code would look in a context manager is the following open file.txt in right mode as f and then f dot write and then you would write hello and then you actually do not need to manually close the file when you open a file in this way so what this does right here is ensure that no matter what happens this file is going to be closed so when you open the file you open it as f you can then do all of your operations inside of this with statement and then as soon as this with statement is done it will automatically close the file and if an exception occurs it will close the file before the program terminates so that is why you use a context manager and really all the context manager is is something that enforces a cleanup operation after this with statement is done whether that be because the program crashed or because it just finished executing all of the statements so there are many other times in which using a context manager is very very important if you want to avoid a bunch of potential problems but really just think of using one whenever you have kind of a cleanup operation that needs to occur now the thing is you can't just use this context manager anywhere this cleanup operation needs to be implemented by something in this case when we use open like this it implements this cleanup operation so it knows okay once i'm done with this i'm going to close the file there's a lot of other things in python that have context managers built in but just wanted to show you here if you are working with files or any resource that needs to be cleaned up try to use a context manager or at least look and see if a context manager is available for the resource that you're trying to use so moving on to the next bad practice which is not using the enumerate function when it's applicable to use it now the enumerate function is something that allows you to get access to the item as well as the index of elements in a list so if we're looking at this example right here we have a list we want to loop through it and we want access to the index so maybe we want to print the index and then we want access to all of the different values all the elements in the list now the traditional way to do this in most programming languages is what you see right here we say 4i in range we go through whatever the length of the list is so loop through all of the indices we get access to the value of each of the items by indexing it in the list and then we print out whatever the index is and the value so let's have a look here we get you know let's scroll here come on zero one one two two three three four so on and so forth now this is fine you can do this it's not that bad but the best practice in python is to do the following for i comma val in enumerate lst print i comma val now you've eliminated this line right here and you've actually made it more readable and easier to find what variable is storing the value of the element and what variable is storing the index so let me just erase this for a second so as i said what enumerate will do is give you the index as well as the value the first item here the first variable here is going to be the index the second value here is going to be the actual value of the item so if i run this we get the exact same result as before and there you go use enumerate in a situation where it makes sense to use it now enumerate doesn't just work with lists it works with any iterable object so work with strings it will work with dictionaries it will work with sets i'll just show you an example with a dictionary so let's say we have hello comma 1 name comma 2 and let's enumerate through i guess let's just call it d now okay and let's run this and now notice we get 0 hello one name we can do the same with a set so one two three okay save and run same thing that works and then finally of course we can do this with a string so hello my name is tim let's run this and notice we get it working as we would expect so that's all for this bad practice just remember this enumerate function exists and you should use it if it makes sense to do so alright so the last bad practice i have for you is another quick one and this is simply to not override built-in names in python what i mean by that is do not name variables things that are python keywords for example do not create a variable called id or a variable called zip you might be tempted to do zip because like a zip code or something right do not name a variable list you do not want to do this the reason why is if you do this you disable or kind of remove the ability to use what these built-in python keywords actually are so if i name a variable id i can now no longer use the id function and the id function gives you the memory address of a python object so if i do idx now you're going to see that i get an error the into object is not callable whereas if i comment this out now i'm still able to use the function so if i wanted to print the id this works it works as a variable as i would expect but again i can no longer use what the actual built-in python function is so you shouldn't name stuff like this you know same goes with zip same goes with list now let's say you really want to name your variable id zip or list or any other built-in python keyword if you really want to do that first of all i'd recommend just don't do it but what you can do is add a trailing underscore this is the convention if you really need to name something a built-in keyword in python then you just put an underscore after you could put an underscore before when you put an underscore before this is the python convention for make this a private attribute or make this a private variable so unless that's what you're intending then you should actually do a trailing underscore so that's all for this last bad practice seems pretty intuitive and straightforward but i cannot tell you how many people do this and it's really frustrating because the syntax highlighting gets all messed up for it and then of course you deactivate the ability to actually use what this built-in keyword is so with that said i think i'm going to end the video here i hope this was helpful if it was make sure to leave a like subscribe to the channel and i will see you in another youtube video [Music] you
Info
Channel: Tech With Tim
Views: 49,503
Rating: undefined out of 5
Keywords: tech with tim, python, code, programming, bad practices, messy code, unreadable code, Mutable Default Parameters, Not Using A Context Manager, Not Using Enumerate, Overriding Built-In Keyboards, python parameters, context manager, context manager python, python enumerate, enumerate, enumerate python, enumerate in python, keywords, default parameters, default parameters in python, python practices, Not Using A Default Dict, defauly dict, vidyard, bad, practices, context, manager
Id: 5Ui37whUDrM
Channel Id: undefined
Length: 19min 27sec (1167 seconds)
Published: Fri Aug 27 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.