exec() is a function which allows you to execute any Python code. You may have seen warnings about using this. Initially it looks like a really great idea because you can execute any Python code that you input into it, which allows you to construct the code from the program and then execute it.
But you have to be extremely careful about this because it can execute any code, and this toy example will show you why this can be dangerous. In this case, elsewhere in my program I happened to have imported the
os module, which gives you lots of useful features to do with the operating system of the computer the program is running on, and it gives us access to lots of really useful functions.
It’s quite common to import
os as it allows you to construct file paths, et cetera. So let’s say that’s happened, and now the rest of our program allows us to input some code which will then be executed. So we’ll have
job = input('Tell me a task to do: '), and now I’m going to be able to input any Python I want, and then we’re going to execute that using
That looks great! So now, instead of me having to write some Python code, I can just enter it and that will run it for me. So let’s see that working. Here we see it running in the manner I intended. It asks for tasks to do, and as you can see, I can enter
and it will execute that, and that works, and that’s great. But the problem is we’ve now allowed the execution of any Python code. Unfortunately, in this case, because I’ve imported the
os module I can execute a program on the system that it’s running on using
os.system() and in this case, just
'ls' , which lists the directory in which the program is running in and we can see all the files that are there. So now running it again, I can use another
os.system() call and remove one of the files which is present—in this case,
And this is why you have to be extremely careful when you use
exec()—because it’s possible to do something which can damage the system. So you have to be very, very careful to ensure that what’s going into
exec() has been completely sanitized, because if not, you could open up yourself to things such as deleting the entire system.
With one command, it would be possible to delete many of the files off the Mac that this is running on. I’m not going to give that as a demonstration. So while
exec() is powerful, it’s best avoided unless you’re sure you’re being really careful with it.
So we can do much the same as we saw before, so if I enter
os.system('ls'), we’ll get a result—and you can also see we have the result
0 because it didn’t return a mathematical value—but it did return the listing.
Lo and behold, that’s gone. If we list that, you can see that
deleteme no longer exists. It’s been deleted and it’s gone forever. There is a way to limit this with
eval(). So after the argument which will be evaluated, you can pass a dictionary.
So here, an empty dictionary will mean that no named functions will be accessible. So now our previous attack using
os will not be accessible, because it’s not in that list of functions. So if I try it this time,
you can see that we get a
os is not defined. To add a function that you would like to access, you can add a dictionary in this format. Here’s the name it will be accessible by, and then you can add the function in—remember, no brackets on the end, as we want to add the function itself.
And now we can use
pow(). So in this case, we can enter
pow(3, 2), and as you can see, that returns a value we would expect. So
eval() can be made safer using this technique, but it’s important to ensure with anything which will execute code, that you are not executing unwanted code at any point.
This is clearly not going to be a problem if you’re the only user of the code, but many has been a time when such code has then been allowed to be used by others and problems have arisen. So be really careful with both
hash() function is extremely useful. It may be something that you’ve heard of when downloading files et cetera for checksums, but simply put, a hash is a one-way function which gives a summary of the contents that it’s been passed. So in this context, it could be a
int, or any other variable or object that has been passed.
but now you’re going to see how this can be useful. If you have two pieces of text which are very similar—so here, the text
'hello from real python!' with an exclamation mark and here, the same text with a full stop (
'.') at the end. One ends in an exclamation mark, one in a full stop, and that’s the only difference between the two. Running this shows that these two hashes are completely different, despite this small difference between the two inputs.
As a result, it’s very quick and easy to see if there’s a difference between two supposedly identical files or inputs. So in that previous example, it was easy to see the difference between the two visually, but here you’re going to see it applied to the entire content of a book, with a single character’s difference between the two. This is going to make use of the file
open() command, which you saw earlier on in the course, but it will be placed inside a context manager. Again, if you’re not sure how to do this, have a look at Real Python’s course on reading and writing files.
And then the
moby_list, which will be a list of each of the lines in that text file, is created using the
file_obj.readlines() method, which reads all of the lines from
file_obj and places them into
That’s the first step, and the file has now been closed, and now we’re going to create two texts. The first one,
moby_1, is using the
.join() method with
moby_list, so that will turn
moby_list into a single string.
At this point, these two are exactly the same, and we can check that by checking the equivalencies of the hashes. So here, the print statement contains the equivalence of hash one and hash two, and if they’re the same, we should see the output
Even writing a
for loop that checked through each character would be a very long-winded way, whereas using
hash() allows you to check quickly and accurately whether two objects are identical—not the same object, but whether their contents’ are identical.
Become a Member to join the conversation.