Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Decoding of Standard Streams

00:00 In the previous lesson, you were introduced to the standard streams of a process. In this lesson, you learn how to decode them. Let’s look at some code, shall we? Please create or open, if you have downloaded the code, a file called magic_number.py, and it doesn’t do very much, but it imports randint from random and then it prints a random integer between 0 and 1000.

00:30 Now this is a py file that we will be calling using subprocess to talk about input and output streams.

00:39 So if you then move to the REPL and import subprocess and then do subprocess.run(), open up your argument list and say python as before.

00:50 But now we are going to call magic_number.py.

00:55 What happens if we run that? Well, it will give us an integer between 0 and 1000. Now in my case, that’s 9. In your case, that will very likely be something else, but it should be between 0 and 1000.

01:10 And as usual, we get our CompletedProcess with the arguments and the return code of 0 telling us there is no error.

01:19 Now at the moment, this output just basically sits here and there’s not much I can do with it. Now ideally, I would like to be able to use that output for something else.

01:29 So there’s two things I’m going to do. First, I’m going to use the up arrow to go back to my previous line of code. And instead of running subprocess just like this, I’m going to again assign it to a completed_process variable.

01:44 And the other thing I’m going to do is I’m going to add an argument that is called capture_output, so capture_output. And I’m going to set that equal to True.

01:57 Now if you run that, what do you get? Not very much. Well, it is what we expected. We are no longer getting this CompletedProcess line because we’ve now assigned it to cp.

02:10 So let’s have a look at cp.stdout. What does that give me? Well, I was expecting a number between 0 and 1000. In fact, I was expecting an integer between 0 and 1000.

02:25 But I get a bytes object, which you can see from the b in front of the string that then gives you the actual integer and the new line. This output is, well, a byte object.

02:38 It is no longer a stream. Remember we said that stdout was a stream that is no longer the case. A stream has been read and has now been stored as a byte object.

02:51 Now the output of your subprocess being a byte object might or might not be what you want. Of course, it depends on what you are going to do with the output, but let’s talk about how to have the output be a string instead of a byte object.

03:07 And there are three ways you can do that. The first way is if you press up twice and you get back to this line here, you can add an argument called text

03:19 and set that to True. Now what does that mean? If this parameter or this argument is set to True, then the subprocess will run in text mode and this means that it will take care of encoding itself.

03:34 So encoding from byte to text. In doing so, it will use its default encoding method and that might not be entirely what you want, but at the moment let’s just have a look at what that does.

03:47 So text=True, you run that. Okay, so then we need to check the output. So stdout and I indeed get a text so that in this case this works.

04:00 But there might be situations where you want to have more control over the exact encoding or decoding that happens to convert your byte object into text. So let’s have a look at that. I’m going to get rid of this text=True because I don’t want to have the default method.

04:19 I want to have a specific method, and for that I need a different argument. And that argument is encoding. I’m going to set that equal to utf-8

04:32 and then run it and then again check cp.stdout

04:38 and then I get a string as expected.

04:42 So that was your second way of doing it where you have the encoding argument in the run() function. The third way of doing this is to use specific decoding on the output.

04:54 So if we get rid of the encoding argument here,

04:59 I do cp.stdout, I can get there using arrows. And you can see this is now again a bytes object. So what I can do is instead of doing cp.stdout, I can add .decode() and then again use utf-8,

05:18 and then I’m back to the string.

05:23 To summarize decoding of standard streams, there are three ways of doing it. The first one is to pass text=True as an argument into the subprocess.run(), and that will give us default encoding, which you might not always want.

05:38 So you can encode explicitly using the encoding argument or you can decode explicitly applying .decode() to the returned bytes object. So much for communication with processes.

05:54 In the next lesson, you will take this a step further by learning about pipes.

Become a Member to join the conversation.