Type hinting is very useful in code editors like VSCode, to stop it from being stupid and claiming it doesn’t know where a lot of attributes or methods come from. For the “Fruit” class example you may find it is helpful to add the type hint in other places where the class instance is used, like if the class instance of “Fruit()” is being passed to a function as an argument. That can help the code editor understand where the attributes and methods attached to that object are coming from, when you use them inside the function. Otherwise it can’t tell that the argument parameter is going to be of type “Fruit” when it is passed to the function. On the other hand, simply creating the class instance from “Fruit()” should be sufficient without type hinting until you go into a different namespace, like the function example.
A pragmatic approach would be to use it wherever it's not inferred. For example, playing around with VS code, I made a class Dog with method bark. Initialising snoopy = Dog() and hovering over snoopy shows that the editor does, in fact, infer that snoppy is a Dog, and using dot notation does show the bark method as an option. For me it all comes down to the question, what do I want from type hints and it's to speed up development by showing me the available methods and to catch errors before running the code.
I only see this with you and i am trying to get used to do it. Still in progress :) . It makes your codes very clean and readable, I like your approach.
aye thanks man, I recently got your course, and I'm still somewhat new to programming and python in general, but I had about 4 months experience when I started your course. however, the way you code, it looked like a different language entirely, I genuinely couldn't tell what I was looking at, as I've never seen somewhat code in such a clean, and experienced way, I had to do a bunch of solo research to figure out half the stuff you programmed and made, more beginner friendly videos like this are helpful.
UNFORTUNATELY they don't do what we think they do lol. I would love for Python to have an opt-in system for static typing, implementing faster interpretation times
That method of always using type annotations is quite clever, I often omit it for "obvious" use cases (such as assigning a string, int, float, or instantiated object), but sometimes you'll make mistakes if you take it too far. I say for assigning values like the above cases, no annotation is fine, but any complex expression should have one if it doesn't document itself perfectly...
banana = Fruit() might be in the first version of your code, but manual editing, global find/replace, and refactoring/renaming might change the right-hand side so that a type annotation on banana in the first place would be important
The only places I place them is when the editor cannot infer the type, so function arguments, or variables that store the return value of an untyped function. That gives maximum type safety with minimal effort.
That and empty sequences are the only valid case where I think type annotations should be used. If the editor can infer the type by itself, adding the type annotation just makes it bloated, distracting and harder to read.
I write single responsibility functions and only annotate function parameters and return types. It was enough, because I've never seen a variable being any type ever in my code where it shouldn't be.
I actually do the same, so I'm not going to complain, but I have had occasions where looking back at my older code, or explaining my code to someone else, has made me stop and think, and have to check some types. Right or wrong, I tend to think that type-hinting every variable is overkill, but then, i do see cases where it helps. it seems no solution is going to be perfect!!
Do you always assign Fruit() to the variable banana straight away ? maybe in some situations you want to declare your variable in the first lines of code and later on you will assign it its value Fruit("some arguments that were not available at first"). In this case it's useful to give the hint. banana : Fruit ... some code ... banana=Fruit()
I straight up avoided python for years because of the typing issues. I always prefer languages like go, rust, swift, etc, not only because of their performance, but also because of the type systems. Now that I found out about typing in python I'm willing to at least give it a chance for projects I need done fast
Works great when you use it in combination with mypy plugin. e.g.: add annotation in function declaration and mypy will tell you whether you return the right type or not.
I am learning python waaaay after the 2->3 transition, and I gotta say i like these “its dynamically typed, but here don’t confuse yourself” features, and probably would have been way more confused before they existed
My view here, type annotation, is a good practice, because it provides a Clea description of what the function is supposed to accept. It s mainly a specification. There a tool like as pylint and editor like visual studio code will help to emphasise type issue. For strict typing my recommendation is to use pydantic. Pydantic implement type verification, even more real constraints. It s a way to make python more similar to a typed language with the power of python libraries.
yeah it doesnt seem to highlight it for types where you can have multiple data types that arent specified exactly like tuples: # Highlighted in Pycharm IDE: a: int = 'hello' b: str = 99 c: dict[str, str] = {1: 1, 2: 2, 3: 3, 4: 4} d: dict = {1, 2, 3} # should be set or set[int] e: str = Something() # Correctly recognized custom class as not str f: list[str] = [1, 1, 1] # Should be list[int] g: tuple[int] = (1, 1, 1) # Should be list[int, int, int]. must be exact # Works fine, as expected: h: tuple[str, str, str] = ('bonjour', 'hi', 'world') # Not caught by the editor when mixed j: list[str] = [1, 1, ''] # Allows it even tho not [str | int] k: list[list] = [1, 1, [5]] # Same here, so long as one element adheres to it. should be [list | int] l: dict[str, str] = {1: "", "": 2, 3: 3, 4: 4} # Not a single one follows format, but str key and str val both exist m: set[str] = {1, 2, ''}
I'm one of those who asked about these hints in the past. Cheers for this video. Anyway, since I'm not that advanced in other languages where it's often compulsory, I think it's a bit messy and unneccessary. I look at it similarly as you describe your dilemma about the "Fruit banana" case. While this "bananagate" is the only case for you where you think it's messy, for me it's messy in all cases. Also, I've checked it now in VS Code and I get the hints regardless whether I specified the type or not. I tried to add the dot behind the variable "print(word.)" and the help popped out in both cases. word = "hello" print(word) word2: str = "hello2" print(word2) I see you use pycharm...ok, now I've checked it in pycharm and it works the same as in vs code. Your video kinda suggests that it doesn't. If you only meant it like the example of what can be seen in the functions than ok. In functions I do see the difference. Now I know more about it and I get it why someone uses it and maybe one day I find the reason too... Thanks.
This maybe intimidating to see from people who haven't experienced typing or people started programming using python. But this will make your life easy working with the large team
If you are using a full fledged IDE, like Pycharm, it is usually smart enough to figure out the type based on the context of how you are using the variables. So doing something like 'banana: Fruit = Fruit()' is pointless or even typing an assignment for something 'banana: Fruit = get_fruit("banana")' is pointless if the function has a return type hinted. However it is great to type hint when you are using a library where the developer wasn't kind enough to type their functions :)
I think i would prefer type: name = .... vs. name: type = .... it is more consistent with other languages e.g. int x = 1 --> int: x = 1 and it also makes it easier to ignore the type if it doesnt matter
The length of the annotations can be quite long...true it is, but otherwise it's straight forward, use the class of the object. For example, for numpy arrays: Incorrect: np.array Correct: np.ndarray You just have to dig in a little deeper.
Nice video, however you should have mentioned type checkers such as mypy. I consider static type checking to be the main benefit and much more important than improved autocompletion in your IDE.
And regarding your debate on class: Fruit =Fruit() Vs Class Fruit() I think the key is to just be consistent in your codebase. If you are using type annotations when declaring and initializing a variable, then do so, even when declaring a class object.
@Indently it's a catch-22! I guess the answer is we should all switch to a statically typed language. I love Python more than chocolate, but with a few modifications like incorporating static typing (and the whole GIL of course), it could be the definitive "best" language, as opposed to an excellent language that has a few shortcomings.
I come from Java and I would prefer `banana = Fruit()`. I think that it's unnecessary to type a variable if it's type is easily known from the right side of the equals. If, for example, you're calling `"hello world".split(" ")` then you could use a type annotation because it may not be completely clear what that function does (This is a simple example). This is what I do in my Kotlin and C# programs and it works for me. In the end, you should just do what you are most comfortable with and stick with it. Consistency is usually the best policy 😂
On your 'Fruit' dilemma. I believe that the key is consistency and sometimes the editor can't infer the type unless you are explicit (happens to me with lists and iterables in Pycharm, it's annoying) -> keep the annotations even if it feels silly.
Ah, that's why you do it, I was bashing you so much about it, but I guess makes sense, I mostly use Idle for simple projects, so I don't need it, I would try this in vs code though
@@0neMadGypsy I really like your way of looking at things, I will try it out of curiositty, he uses py charm, so I wanna see how vs code handles it, but I agree with you 💯%, altought sometimes is faster that editor holds your hand, I prefer it the hard way, you learn and memorise alot more, sometimes vs code is handy like with prettify so you can see jsons structures better
How about C# where you can put "Fruit fruit = new();" no redundancy at all! Or you can use "var fruit = new Fruit();". You decide where the type "Fruit" should go but you don't need to ever specify it twice in the same line.
@@memes_gbc674 oh how cute. Someone who still (in 2023) thinks that C# is just Java. Do yourself a favor and actually learn C#. I find that the only people ignorant enough to claim that C# and Java are the same are the ones that either don't know Java, don't know C# or don't know either. Take it from someone who has used them both in a professional context for over a decade now. They are NOT the same language. Even the creator of C#, Anders Hejlsberg, said that C# is closer to C++ than Java and that was in the very early days of C#. At this point C# is far, far different from both Java and C++. Maybe you are just trolling, but if you aren't and you legitimately believe what you say, then please do yourself a favor and educate yourself.
Not like Java! banana: fruit = Fruit() does not look like Java, which is: var banana = new Fruit(); The difference though is that the Java line still enforces type, both at run time and in the editor. In a less cluttered language like Python or Java, one would just write though: Fruit banana or Fruit banana, apple, tomato to get default-initialized objects.
You should always use type annotations no matter what. You'll write less bugs and you can use doc strings to give important information about the class.
Type hinting is very useful in code editors like VSCode, to stop it from being stupid and claiming it doesn’t know where a lot of attributes or methods come from. For the “Fruit” class example you may find it is helpful to add the type hint in other places where the class instance is used, like if the class instance of “Fruit()” is being passed to a function as an argument. That can help the code editor understand where the attributes and methods attached to that object are coming from, when you use them inside the function. Otherwise it can’t tell that the argument parameter is going to be of type “Fruit” when it is passed to the function. On the other hand, simply creating the class instance from “Fruit()” should be sufficient without type hinting until you go into a different namespace, like the function example.
The content of this channel is a treasure 🖤
7:38 "I'm always split about which approach to take." That was a great unintentional pun: banana...split...amirite?
A pragmatic approach would be to use it wherever it's not inferred. For example, playing around with VS code, I made a class Dog with method bark. Initialising snoopy = Dog() and hovering over snoopy shows that the editor does, in fact, infer that snoppy is a Dog, and using dot notation does show the bark method as an option. For me it all comes down to the question, what do I want from type hints and it's to speed up development by showing me the available methods and to catch errors before running the code.
I only see this with you and i am trying to get used to do it. Still in progress :) . It makes your codes very clean and readable, I like your approach.
aye thanks man, I recently got your course, and I'm still somewhat new to programming and python in general, but I had about 4 months experience when I started your course. however, the way you code, it looked like a different language entirely, I genuinely couldn't tell what I was looking at, as I've never seen somewhat code in such a clean, and experienced way, I had to do a bunch of solo research to figure out half the stuff you programmed and made, more beginner friendly videos like this are helpful.
UNFORTUNATELY they don't do what we think they do lol. I would love for Python to have an opt-in system for static typing, implementing faster interpretation times
That method of always using type annotations is quite clever, I often omit it for "obvious" use cases (such as assigning a string, int, float, or instantiated object), but sometimes you'll make mistakes if you take it too far. I say for assigning values like the above cases, no annotation is fine, but any complex expression should have one if it doesn't document itself perfectly...
banana = Fruit() might be in the first version of your code, but manual editing, global find/replace, and refactoring/renaming might change the right-hand side so that a type annotation on banana in the first place would be important
I'm such a huge fan of Python. Absolutely love each of your videos brother! 🎉❤
The only places I place them is when the editor cannot infer the type, so function arguments, or variables that store the return value of an untyped function. That gives maximum type safety with minimal effort.
That and empty sequences are the only valid case where I think type annotations should be used. If the editor can infer the type by itself, adding the type annotation just makes it bloated, distracting and harder to read.
I write single responsibility functions and only annotate function parameters and return types. It was enough, because I've never seen a variable being any type ever in my code where it shouldn't be.
I actually do the same, so I'm not going to complain, but I have had occasions where looking back at my older code, or explaining my code to someone else, has made me stop and think, and have to check some types.
Right or wrong, I tend to think that type-hinting every variable is overkill, but then, i do see cases where it helps. it seems no solution is going to be perfect!!
Do you always assign Fruit() to the variable banana straight away ? maybe in some situations you want to declare your variable in the first lines of code and later on you will assign it its value Fruit("some arguments that were not available at first"). In this case it's useful to give the hint.
banana : Fruit
...
some code
...
banana=Fruit()
I straight up avoided python for years because of the typing issues. I always prefer languages like go, rust, swift, etc, not only because of their performance, but also because of the type systems. Now that I found out about typing in python I'm willing to at least give it a chance for projects I need done fast
Works great when you use it in combination with mypy plugin. e.g.: add annotation in function declaration and mypy will tell you whether you return the right type or not.
I think it's a shame that this doesn't raise an exception:
text: int = 'hello'
Is it possible to get python to abort with an error in such a case?
I am learning python waaaay after the 2->3 transition, and I gotta say i like these “its dynamically typed, but here don’t confuse yourself” features, and probably would have been way more confused before they existed
My view here, type annotation, is a good practice, because it provides a Clea description of what the function is supposed to accept. It s mainly a specification. There a tool like as pylint and editor like visual studio code will help to emphasise type issue. For strict typing my recommendation is to use pydantic. Pydantic implement type verification, even more real constraints. It s a way to make python more similar to a typed language with the power of python libraries.
yeah it doesnt seem to highlight it for types where you can have multiple data types that arent specified exactly like tuples:
# Highlighted in Pycharm IDE:
a: int = 'hello'
b: str = 99
c: dict[str, str] = {1: 1, 2: 2, 3: 3, 4: 4}
d: dict = {1, 2, 3} # should be set or set[int]
e: str = Something() # Correctly recognized custom class as not str
f: list[str] = [1, 1, 1] # Should be list[int]
g: tuple[int] = (1, 1, 1) # Should be list[int, int, int]. must be exact
# Works fine, as expected:
h: tuple[str, str, str] = ('bonjour', 'hi', 'world')
# Not caught by the editor when mixed
j: list[str] = [1, 1, ''] # Allows it even tho not [str | int]
k: list[list] = [1, 1, [5]] # Same here, so long as one element adheres to it. should be [list | int]
l: dict[str, str] = {1: "", "": 2, 3: 3, 4: 4} # Not a single one follows format, but str key and str val both exist
m: set[str] = {1, 2, ''}
Have you tried Mojo? :) Language which suppose to be superset of Python with strong typing :)
I'm one of those who asked about these hints in the past. Cheers for this video. Anyway, since I'm not that advanced in other languages where it's often compulsory, I think it's a bit messy and unneccessary. I look at it similarly as you describe your dilemma about the "Fruit banana" case. While this "bananagate" is the only case for you where you think it's messy, for me it's messy in all cases. Also, I've checked it now in VS Code and I get the hints regardless whether I specified the type or not. I tried to add the dot behind the variable "print(word.)" and the help popped out in both cases.
word = "hello"
print(word)
word2: str = "hello2"
print(word2)
I see you use pycharm...ok, now I've checked it in pycharm and it works the same as in vs code. Your video kinda suggests that it doesn't. If you only meant it like the example of what can be seen in the functions than ok. In functions I do see the difference.
Now I know more about it and I get it why someone uses it and maybe one day I find the reason too... Thanks.
There are cases such as the ones you mentioned that it will work regardless, but try it with function parametres.
Personally I only use type annotations in functions to have hints from vscode and sometimes just to be very explicit
This maybe intimidating to see from people who haven't experienced typing or people started programming using python. But this will make your life easy working with the large team
If you are using a full fledged IDE, like Pycharm, it is usually smart enough to figure out the type based on the context of how you are using the variables. So doing something like 'banana: Fruit = Fruit()' is pointless or even typing an assignment for something 'banana: Fruit = get_fruit("banana")' is pointless if the function has a return type hinted.
However it is great to type hint when you are using a library where the developer wasn't kind enough to type their functions :)
Can you please make a video on how to use ravel() function ?
I think i would prefer type: name = .... vs. name: type = ....
it is more consistent with other languages e.g. int x = 1 --> int: x = 1 and it also makes it easier to ignore the type if it doesnt matter
I also love type annotations, but with modules like numpy they are just so painful to work with
The length of the annotations can be quite long...true it is, but otherwise it's straight forward, use the class of the object. For example, for numpy arrays:
Incorrect: np.array
Correct: np.ndarray
You just have to dig in a little deeper.
@@Andrumen01 Ye I tried that, but it keeps raising warnings.
@@INGIE32 Are you using Pycharm?
You might have to write something like:
var = np.array([1,2,3]) # type: np.ndarray
Does that work?
Good entry level video, but why don't you mention static type checkers (mypy, pyre, pytype) if you are talking about type safety?
numpy???????
@@EnzoSantos sorry, I meant mymy, not numpy
Nice video, however you should have mentioned type checkers such as mypy. I consider static type checking to be the main benefit and much more important than improved autocompletion in your IDE.
You’re right, I’m actually making a free 3 hour course that talks about mypy as well since there’s a lot that pycharm doesn’t catch :)
There could be some information about pydantic. Absolutely fantastic lib based on type checking
Very nice and informative video👏🔥
you use type annotation because it self documents your code, i use type annotations because it makes me look smart
we are not the same
And regarding your debate on class: Fruit =Fruit()
Vs
Class Fruit()
I think the key is to just be consistent in your codebase. If you are using type annotations when declaring and initializing a variable, then do so, even when declaring a class object.
I agree with the consistency approach, but even so, I feel wrong if I annotate banana: Fruit, and I feel wrong if I don't ahaha.
@Indently it's a catch-22! I guess the answer is we should all switch to a statically typed language. I love Python more than chocolate, but with a few modifications like incorporating static typing (and the whole GIL of course), it could be the definitive "best" language, as opposed to an excellent language that has a few shortcomings.
Great video. Thanks
its always good to use type annotations. Four example your banana case, well banana might not always mean a fruit.
I come from Java and I would prefer `banana = Fruit()`. I think that it's unnecessary to type a variable if it's type is easily known from the right side of the equals. If, for example, you're calling `"hello world".split(" ")` then you could use a type annotation because it may not be completely clear what that function does (This is a simple example). This is what I do in my Kotlin and C# programs and it works for me. In the end, you should just do what you are most comfortable with and stick with it. Consistency is usually the best policy 😂
I always use them, even if the assignment seems redundant
Typically not a fan of Python for this reason so I’m glad to see the there are advocates for making types explicit
On your 'Fruit' dilemma. I believe that the key is consistency and sometimes the editor can't infer the type unless you are explicit (happens to me with lists and iterables in Pycharm, it's annoying) -> keep the annotations even if it feels silly.
Ah, that's why you do it, I was bashing you so much about it, but I guess makes sense, I mostly use Idle for simple projects, so I don't need it, I would try this in vs code though
@@0neMadGypsy I really like your way of looking at things, I will try it out of curiositty, he uses py charm, so I wanna see how vs code handles it, but I agree with you 💯%, altought sometimes is faster that editor holds your hand, I prefer it the hard way, you learn and memorise alot more, sometimes vs code is handy like with prettify so you can see jsons structures better
Thank you so much 🙂❤
You could have added some minutes on usage of mypy to check typing.
I really like Python but the type system with the type annotations is just a joke.
What? It's just type checking and very useful for working with large team. You can ignore it unlike if the project is made of typescript.
Python is a joke, too. I wish I wouldn't have to use it and just use Typescript
@@datoubi typescript is a worse joke
Isn't this a reupload?
fruit Fruit = new Fruit();
Java is awesome.
How about C# where you can put "Fruit fruit = new();" no redundancy at all! Or you can use "var fruit = new Fruit();". You decide where the type "Fruit" should go but you don't need to ever specify it twice in the same line.
Actually
Fruit fruit = new Fruit();
😅 types come before identifiers
@@pharoah327 I like this feature a lot
@@pharoah327 C# is literally java but not 30 years old
@@memes_gbc674 oh how cute. Someone who still (in 2023) thinks that C# is just Java. Do yourself a favor and actually learn C#. I find that the only people ignorant enough to claim that C# and Java are the same are the ones that either don't know Java, don't know C# or don't know either. Take it from someone who has used them both in a professional context for over a decade now. They are NOT the same language. Even the creator of C#, Anders Hejlsberg, said that C# is closer to C++ than Java and that was in the very early days of C#. At this point C# is far, far different from both Java and C++. Maybe you are just trolling, but if you aren't and you legitimately believe what you say, then please do yourself a favor and educate yourself.
The arrow return annotation is also useful
Help, I have studied too much Java...
FruitList bananas = new FruitList(Banana);
We want a video about mojo lang plz
Do you think that what I think is what you think that I think? Python annotations do exactly what I think they do.
You forget the generic alias
Not like Java!
banana: fruit = Fruit()
does not look like Java, which is:
var banana = new Fruit();
The difference though is that the Java line still enforces type, both at run time and in the editor.
In a less cluttered language like Python or Java, one would just write though:
Fruit banana
or
Fruit banana, apple, tomato
to get default-initialized objects.
i would typehint banana, just to be consistent
Great
You should always use type annotations no matter what. You'll write less bugs and you can use doc strings to give important information about the class.