back to index6 of Python's Newest and Best Features (3.7-3.9)
Chapters
0:0 Intro
0:35 Breakpoint
1:57 Walrus Operator
6:28 Sign specifier
7:43 Positional parameters
10:56 Type hinting
16:26 Dictionary unions
00:00:00.560 |
Hi and welcome to this video, we're going to go through 00:00:03.600 |
and take a look at some of the coolest, more interesting 00:00:07.360 |
features that have been added into Python in the past few years. 00:00:11.200 |
So we'll just go straight into it and code a few examples as well. 00:00:15.760 |
Okay so the first one and the only example we're going to look at from 00:00:24.160 |
So obviously a breakpoint is where we typically click 00:00:28.240 |
on the left side of our editor to add in the little red circle, which means we 00:00:32.720 |
want the code to break at this point. What the breakpoint function allows us 00:00:38.160 |
to do is actually use Python debuggers within our code. 00:00:42.960 |
So the function uses the bdb debugger by default 00:00:47.520 |
but we can also use other alternatives as well. 00:00:51.200 |
So for example if we had a list of functions here, a list of 00:00:58.960 |
Okay so they just print out "hello". If we for whatever reason 00:01:06.160 |
wanted to put in a breakpoint to try and figure out what was going wrong, 00:01:10.560 |
say this code was probably a little more complicated, 00:01:17.440 |
Okay and then we go straight into the Python bdb 00:01:22.240 |
debugger at the bottom here and this is essentially like a 00:01:26.000 |
interactive shell where we can just write Python and 00:01:29.200 |
figure out what is going on. So obviously there's not really much for us to figure 00:01:33.680 |
out in this case but when you're actually writing 00:01:37.840 |
more complex functions or classes or modules in your 00:01:41.360 |
code this can be really really useful. So here we can print 00:01:49.200 |
or do anything. It's simply an interactive Python debugger window. 00:01:57.600 |
So the second of our new features actually comes from Python 3.8. 00:02:03.280 |
Now this is the walrus operator which was the go-to for the majority of 2019 00:02:09.440 |
for anyone covering what is new in Python 3.8. 00:02:13.840 |
So it's a new operator added to Python. It's genuinely very useful. 00:02:19.040 |
It essentially allows us to assign a value to a variable on the fly. 00:02:23.520 |
So it looks like this which looks like a walrus hence the name 00:02:26.880 |
and we can use it to write more compact code. 00:02:43.280 |
and then we want to write an if statement checking 00:02:52.640 |
And if so we want to print out the length t_length 00:02:59.920 |
and a little statement saying that this is greater than 3. 00:03:05.440 |
That's great. With the walrus operator we can actually make this more 00:03:25.840 |
So we put this within a bracket and then we change our equal sign here 00:03:31.040 |
to a walrus operator and we can run that again 00:03:38.640 |
So then we've shortened our code made it more compact. 00:03:43.200 |
Obviously you know whether this is useful and more readable 00:03:54.400 |
understand and use. So a more realistic use case for this could be 00:04:01.040 |
if we are writing a regex statement. So I'll just write out a sentence here 00:04:14.960 |
Okay so we want this sentence to go through and 00:04:19.600 |
use regex to find a currency followed by a few numbers. 00:04:28.320 |
So we're going to go through each of these sentences and only print out the 00:04:44.640 |
Now for those of you that use regex a fair bit before 00:04:48.240 |
you'll know that when we use a regex search it will 00:04:51.600 |
return either none or return a set of groups which contain 00:04:56.400 |
our matches and typically what we'd have to do 00:05:00.320 |
is we'd have to write amount equals re.search and then we would have 00:05:22.480 |
before a set of digits and this will return just digits not the 00:05:31.840 |
Okay and usually you would have to do this and then we would have to write 00:05:41.280 |
or just if amount is true and then print out the amount and the 00:06:03.840 |
but what we can do instead is use our walrus operator. 00:06:14.640 |
and now we've shortened our code. So that's more probably a more useful 00:06:24.400 |
example of using the walrus operator. Another really cool feature that was 00:06:41.680 |
So we have these two variables it's just two numbers 00:06:47.040 |
and maybe we are trying to figure out maybe we're doing something wrong and we 00:06:51.520 |
want to see where our values are going and what 00:06:54.720 |
variables are being assigned to and what we might typically do 00:07:13.440 |
Okay and this is probably what a lot of us would do 00:07:19.360 |
but rather than doing this we can actually just write 00:07:30.560 |
and this will print out the same thing. So it shows the variable name and the 00:07:37.040 |
value within it. So it's a smaller but I think very useful addition to Python. 00:07:44.480 |
Okay so the final feature from Python 3.8 is the inclusion 00:07:48.240 |
of syntax to specify the input parameters the functions that cannot be 00:07:53.920 |
called by name but instead by the position. So what I 00:08:20.880 |
which is using the position of the parameters in order to 00:08:24.240 |
fill in those variables or we can also do this 00:08:30.640 |
and we'll get the exact same output. Now this is great but when you're writing 00:08:45.280 |
code that other people are using and relying on and maybe that 00:08:49.600 |
code isn't completely finished yet you may find 00:08:52.640 |
that you are not entirely sure if you'll keep 00:08:54.800 |
this variable or input parameter as op or this is x or this is y you might 00:09:01.120 |
change these around and if people are using your code like 00:09:08.320 |
change your code to use different variable names. 00:09:12.080 |
So maybe at a later point you decide you would change your code to 00:09:16.880 |
use method instead of op. If we took that and then tried to use this 00:09:22.960 |
function again we'd get this type error. Obviously we 00:09:33.520 |
is define method as a positional only parameter and we do that 00:09:40.720 |
by adding this slash. So now if we try to run this 00:09:50.000 |
we see okay we have a type error count got some positional 00:09:58.480 |
only arguments passes keyword arguments. So although we haven't changed 00:10:03.040 |
operator to method yet we are preventing the user 00:10:06.640 |
from using op here. So that forces the user to use this 00:10:28.800 |
but they cannot use anything that comes before this slash. So if we 00:10:34.480 |
do rewrite our function to use method instead of op 00:10:43.520 |
and the user runs their code that they've been using before 00:10:47.760 |
we won't get any errors because we've prevented the user from being able to 00:10:56.480 |
Okay so that's everything for Python 3.8 and we're going to move on to Python 00:11:05.600 |
is the addition of more type hinting. So type hinting is something that has been 00:11:09.680 |
around for a while and it seems to be a recurring theme 00:11:13.440 |
with every Python update that we will get some new 00:11:20.800 |
they've essentially merged all the different type hinting 00:11:24.240 |
features that they've been adding over time and brought them into the core 00:11:28.000 |
Python functionality. So there's no more importing 00:11:31.680 |
typing modules or annotation modules just works 00:11:35.120 |
as it is for the most part. So for those of you that don't know what 00:12:03.280 |
Okay but it can be used because we're just using a plus here so 00:12:08.560 |
it's essentially telling Python to concatenate these two strings but our 00:12:12.320 |
intention is actually to only allow integers. 00:12:15.680 |
So what we can do is add a type annotation or a type hint 00:12:23.680 |
and that's what this is here. So we add this colon followed by 00:12:27.280 |
the data type that we intend this value to be. 00:12:37.920 |
Now when you are writing this code out in your editor 00:12:43.600 |
and you have your Python linter so pylint for example 00:12:48.000 |
it will come up with an error if you write something like this 00:12:52.640 |
later on. And this isn't an error that will stop 00:12:55.840 |
your code. We can still run it. It is just a hint, it is a warning. Okay you 00:13:01.920 |
can't see it here because we're in Jupyter but in a normal editor with 00:13:06.560 |
pylint installed you will see this bit here get highlighted 00:13:27.440 |
the warning that will pop up. Now this is just 00:13:30.720 |
very useful for complex code bases where you're not entirely sure 00:13:34.880 |
what values are supposed to be going in and out of different functions and 00:13:41.920 |
follow. Another syntax addition in terms of the 00:13:47.200 |
type hinting that was added is the ability to 00:13:50.000 |
define the type that should be coming out of a function not just into a 00:13:56.160 |
Say here we want to sum up all the values within a 00:14:05.920 |
We want to input a dictionary and what we would expect to get out of 00:14:14.400 |
syntax here as an integer. Then we just return the sum 00:14:27.760 |
Then we define our dictionary here and we can also add the type here as 00:14:46.560 |
Then we call our function and we should get a 00:14:53.200 |
integer out of that as expected. Now if we change this and these were the 00:14:59.600 |
other way around and we had strings instead of numbers here we would 00:15:04.000 |
obviously get a full-blown error but before we 00:15:06.880 |
even ran that we would see a type hint come up 00:15:14.080 |
not a string. So it can be very useful and just 00:15:17.920 |
in terms of readability it can depending on how you do this be very 00:15:24.080 |
very useful. If you look into complex libraries 00:15:27.200 |
like you have the TensorFlow library or Transformers library those libraries 00:15:30.880 |
with type hints can make things a lot easier. 00:15:33.200 |
In fact some of the more recently written code in the Transformers library 00:15:38.800 |
has been using type hinting and it makes it so much easier to read. 00:15:44.000 |
So it's a very good addition to Python in my opinion. 00:15:48.960 |
Now something that is very useful if we take this function again 00:15:55.120 |
we can actually use more complex types. So we know that we want a 00:16:02.000 |
dictionary but maybe you want to define what is 00:16:04.640 |
within that dictionary as well. So we can actually do that like this. 00:16:09.760 |
So now we know that our dictionary should be built of string keys 00:16:16.400 |
and integer values and this is just an extra layer of detail so we can be 00:16:22.880 |
more specific. There we go. Now the final feature in Python 3.9 that 00:16:30.320 |
we'll go over is dictionary unions operators. 00:16:34.880 |
There's quite an interesting addition to the syntax 00:16:38.320 |
and it gives us two new operators. One is called the merge operator 00:16:42.720 |
and the other is the update operator. So the merge operator looks like this 00:16:48.560 |
and we use it to merge two dictionaries. So let's write out two 00:16:59.040 |
Okay so we have these two dictionaries and we can merge them using our merge 00:17:05.360 |
Okay and now we can see that those two dictionaries are now one 00:17:15.120 |
within our new variable C. The update operator is slightly different 00:17:19.680 |
in that it allows us to do the merge in place. 00:17:23.600 |
So what that means is rather than adding this to a new variable 00:17:30.240 |
we actually assign it to the variable on the left of the statement and this here 00:17:43.040 |
we see that we get the same function. Okay so that's it for this video 00:17:49.200 |
covering some of the biggest changes and upgrades 00:17:52.160 |
to Python that we actually see and use on a daily 00:17:59.680 |
you've enjoyed and as always thank you for watching, bye!