Python 3.8 stable is out now. It has some really cool new features. The question here is should you really upgrade?
Python 3.8 Features
Let’s talk about them one by one.
f-strings Supports = for easy debug and logging
Let’s understand this by example.
>>> tutorial_title = 'Python 3.8 Features - Should You Upgrade?' >>> format_code = True |
Now if we want to check the values at run time, we usually write like this:
>>> print (f 'tutorial_title={tutorial_title}, format_code={format_code }' ) tutorial_title = 'Python 3.8 Features - Should You Upgrade?' , format_code = True |
With Python 3.8, adding an =
at the end of expression will print the expression and its value.
>>> print (f '{tutorial_title=}, {format_code=}' ) tutorial_title = 'Python 3.8 Features - Should You Upgrade?' , format_code = True |
This works with loggers too:
>>> logging.info(f '{tutorial_title=}, {format_code=}' ) INFO:root:tutorial_title = 'Python 3.8 Features - Should You Upgrade?' , format_code = True |
I have already updated the code that I wrote for the comprehensive tutorials on web scraping.
[convertkit form=1008295]
Python 3.8 Feature – The Walrus Operator :=
This operator is called the Walrus operator. The reason is that it looks like a pair of eyes and tusks of a walrus.
This is actually an assignment expression. Here is an example:
1 2 3 4 | # Python 3.7 Way name = input ( 'Please Enter Name: ' ) if len (name) > 20 : print (f 'ERROR: Name too big. Allowed (20). Actual {len(name)}' ) |
Note that in the above code len()
function was called two times.
The other way is to store the result of len()
in a variable.
1 2 3 4 5 | # Python 3.7 Way name = input ( 'Please Enter Name: ' ) name_length = len (name) if name_length > 20 : print (f 'ERROR: Name too big. Allowed (20). Actual {name_length}' ) |
With our friend walrus in Python 3.8, there is a new way to do the same thing:
1 2 3 4 | # Python 3.8 Way name = input ( 'Please Enter Name: ' ) if (n: = len (name)) > 20 : print (f 'ERROR: Name too big. Allowed (20). Actual {n}' ) |
It looks pretty cool and can actually be very useful in many cases
This should be used as minimum as possible. It makes code less readable and error-prone.
Positional-Only Parameters
Next Python 3.8 feature is a parameter syntax /
to indicate that the function parameters preceding this /
cannot be used as keyword arguments.
There are three ways to call to send function parameters in Python:
- Parameters by Position –
do_something(10,2)
- By Keywords –
do_something(base=10,exp=2)
- By Keywords OR Position –
do_something(10,exp=2)
Take a look at help on len()
function in python 3.7
Did you notice the /
as the “second parameter”? It is a modifier for a first parameter.
It means that calling len
with keywords obj
is not valid. This is called a position-only parameter.
1 2 3 4 5 6 | >>> len ( "Upendra" ) 7 >>> len (obj = "Upendra" ) Traceback (most recent call last): File "<stdin>" , line 1 , in <module> TypeError: len () takes no keyword arguments |
This is logical, as the obj
keyword will actually affect readability.
Until Python 3.7, using /
to denote position only parameter was not possible for user-defined functions. Now we can very well have a function definition like:
1 2 3 4 5 6 7 8 9 10 | def do(a, b, / , c, d, * , e, f): print (a, b, c, d, e, f) # a, b are positional-only # c, d can be positional or keyword # e, f keyword-only do( 10 , 20 , 30 , d = 40 , e = 50 , f = 60 ) # VALID do( 10 , b = 20 , c = 30 , d = 40 , e = 50 , f = 60 ) # INVALID b cannot be a keyword argument do_something( 10 , 20 , 30 , 40 , 50 , f = 60 ) # INVALID e must be a keyword argument |
/
makes arguments BEFORE it position-only arguments *
makes arguments AFTER it keyword-only arguments
This has been discussed in length at PEP 457.
More Python 3.8 features
There are many Python 3.8 features that we can talk about. This one, for example, is small but very useful.
- When a comma is missed in code such as
[(10, 20) (30, 40)]
, the compiler displays aSyntaxWarning
with a helpful suggestion:
1 2 | >>> numbers = [( 10 , 20 ) ( 30 , 40 )] <stdin>: 1 : SyntaxWarning: 'tuple' object is not callable ; perhaps you missed a comma? |
New Modules
Now you can read metadata from packages using the module importlib.metadata
1 2 3 4 5 6 | # after installing requests >>> from importlib.metadata import version, requires, files >>> version( 'requests' ) '2.22.0' >>> list (requires( 'requests' ))[: 2 ] [ 'chardet (<3.1.0,>=3.0.2)' , 'idna (<2.9,>=2.5)' ] |
Should You Upgrade?
Generally speaking, a new version fixes a lot of bugs. Furthermore, whatever worked with Python 3.7 should work with Python 3.8.
Consequently, it should be an easy answer: Yes!
Nevertheless, it would eventually come down to the dependencies you are using. Not all the libraries and modules that you are using, are guaranteed to work with 3.8.
The good news, though, is you can have both 3.7 and 3.8 installed on your machine.
You can easily use virtual environments and test your code for both versions and decide.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Using pipenv to create virtual environments # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 1. Creates virual environment with version 3.8 in current path pipenv - - python 3.8 # 2. Creates virual environment with version 3.7 in current path pipenv - - python 3.7 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # using virtalenv to create virtual environments # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # 1. Creates virual environment with version 3.8 virtualenv - - python = "C:\Program Files\Python38\python.exe" <target path> # 2. Creates virual environment with version 3.7 virtualenv - - python = "C:\Program Files\Python37\python.exe" <target path> |
You can head over to the official page if you want to look at the complete list of everything that Python 3.8 has to offer.
Which Python 3.8 feature did you find most interesting?