Python for the .NET Developer Transcripts
Chapter: The Python Language
Lecture: Python type annotations
0:00 If you've been longing for types, somewhere, somehow in this code, to show up and say, you know this next it's actually an integer
0:09 or the return value of this thing is a list of numbers or something like that. Well, since Python 3.4, we've had the ability
0:19 to specify types, much like Typescript for Python. Typescript lets you optionally add types it's a little more constrictive
0:28 than what you'll see in Python but you can either run plain Python or you can have Python with types these days in Python 3.
0:35 So we're going to explore that, and this Python with types, in a limited degree, is actually the kind
0:40 that I like best. You'll see that some parts of your code don't need any typing and some parts it actually benefits
0:46 them a lot and lights up the editors like Pycharm and VS Code and so on and it's totally worth it. Now I know we haven't yet gotten to classes
0:54 and we're going to focus more on that in a little bit but I'm going to use a class here so we can have a type
0:59 to find here, okay? So, if a little bit of the details of the class are vague, don't worry about it
1:03 remember next chapter we're diving into classes deep. So what we're going to do here, is we're going to define a class
1:09 which is a wizard. Let's remember what the C# one had. We had a class which is a Wizard and they had a string name and an integer level.
1:21 So, for Python classes we go to the constructor to define the fields not necessarily at the top level. Can do it at the top level
1:29 but we're going to talk about that later. So we have not a constructor method or a wizard or whatever we just have a what's called a __init__
1:37 double underscore init and down here we don't have a this we have a self, so we say self.name = let's put a W for the wizard
1:46 and self.level is going to be equal to 0. And then what do we have over in the C# world? We had a static wizard method so let's go over here
1:57 and define a train method. And it's going to return a wizard and this is going be a staticmethod. Right. That's what it was before. In C# it was static
2:07 goes there, in Python it was here. We'll talk again about that in the classes and what we're going to do is we're going to create a Wizard.
2:17 This is like new, but you don't say the new keyword. Then we say let's set the base level here which is an integer as we'll see.
2:27 Notice there's a level, right, got dot level so it's understood this is this type but it doesn't really have the typing yet, it's just the editor's
2:34 being really smart. And, yeah, let's just say, we're just going to leave the name alone, some wizard, I don't know.
2:43 We could pass this in but the one we did in C# didn't have it so let's just leave it like that. Alright, so here is the definition of a class
2:50 that is almost like the one we have in C# it has a name and a level, it has a train method and it returns a wizard. Did I actually return it? No.
2:58 There. Now we have like what we had in C# and we don't want this self method for a primer
3:05 for static methods. Okay super, so this is looking pretty good and then we had this main business down here.
3:12 And what we said is that Gandolf is a Wizard.train set the base level of 7, over here it's going to be 100
3:21 and then we print it out that something like the wizard is some level, I'm going to say gandolf.level, like so.
3:29 PyCharm thinks this is misspelled of course it's not, right? Alright, so let's run this and see what we get. Does it behave? Excellent.
3:36 Oh, it didn't level it up. Right, that's the other thing we did. We said gandolf.level += 1. Now it's 101. Perfect. That's what we expect.
3:47 And you might be wondering, okay, well I guess there's a class but where's the types, Michael? They're not here. Yet.
3:54 This is the untyped version. But Python, like I said since version 3.4, we are on 3.7 you can see
4:02 down here on the right, since 3.4 you can define types. Actually it's a rich typing system that describes.
4:09 So I can come over here and say, in C# I would say something like string name or in Python's types I'd say str name. That's not how it works here.
4:19 It's more Typescript like. You say the variable and then the type, so name colon str and name colon int. So now when I go over here and I say dot level
4:30 dot, notice it's offering auto complete for integers. How cool is that? Okay. So it knows that this is an integer
4:39 and down here I can go to this method and say this method takes an integer and then it has a return value which is this arrow here like that
4:49 and we're going to return a Wizard is what you want to say. There's a small challenge about the way that the parsing order happens in Python
4:59 so when you're talking within a class that it returns that class, you have to put this in quotes. But notice it has it like colored to say
5:07 no, this is a special thing, not just a string. Okay? So now if I go over here and I could work with this.
5:14 We could say this is a wizard and then gandolf dot name obviously it knows that's a string but if I said this is something else
5:24 I'm defining it to be an integer it gives you a big warning and says no, no, no you can't assign a wizard to an integer and down here
5:31 it says the integer doesn't have a level. What, are you crazy? Right, so you can either omit this and it probably can figure out that that's a wizard
5:39 you can see it's doing this here. But if you want to be super explicit or some reason it doesn't pick it up, you can say this is a wizard.
5:47 Double e here right or for some reason this method didn't say what it is but you know what it is go like that.
5:53 So check this out. We have Python with types. Try it again. It works fine. One thing to notice though, this is like an editor helper
6:02 type thing. If this is an integer in C# this would crash. Here it just keeps running, right? You get this warning in the editor but you don't get
6:11 runtime validation. Rarely, not never, but rarely does the typing information actually get taken into
6:17 account. For runtime it's for continuous integration tools and linters and definitely for editors
6:23 like Pycharm and VS Code. So that's a real big difference. But you can have types. Now, one more thing we want to do here.
6:30 Why would I give this name as always some other? That's weird. I could just set it to be none and then people could specify what the level is, right?
6:37 Now notice there's an error. In C#, strings are reference types. In Python, everything is a reference type. Everything.
6:47 Even numbers are reference types. In C# world they should be able to be set to null they're None in Python, right?
6:53 The type system is more specific and it has special handling for things that can both have a value and be none.
7:01 You have to explicitly say this is a nullable string even though it's a reference type. So notice here, does expect the string got None.
7:07 So what we have to put an optional string. What is optional? This is defined in a library called typing. The top, run typing, import optional.
7:19 Now, our none error went away. Right? We could do the same thing if we didn't want to start with a zero value, we could have an optional int
7:26 set to None. Let's run it one more time. The wizard gandolf is at 101 with all sorts of type validation in Python. I think that's pretty cool.