Look at the Python website documentation whatsNew, Python 3.10 is getting closer and closer, so let’s take a look at how Python 3.10 compares to Python 3.9
New features
Multiple context managers are organized by parentheses
** ** ** ** ** ** ** ** ** ** ** *
with open("read.txt"."r") as rfile:
with open("write.txt"."w") as wfile:
wfile.write(rfile.read())
Copy the code
Will it come to this, [facepalm][facepalm][facepalm]
So in Python3.10, we can write:
with (
open("read.txt"."r") as rfile,
open("write.txt"."w") as wfile
):
wfile.write(rfile.read())
Copy the code
More friendly error messages
Grammar mistakes
- In the code
Brackets or quotes are not closed
The interpreter can provide the exact starting position of the error
For example, the following error code (because the braces are not closed) :
# filename: syntax_error_1.py
expected = {9: 1.18: 2.19: 2.27: 3.28: 3.29: 3.36: 4.37: 4.38: 4.39: 4.45: 5.46: 5.47: 5.48: 5.49: 5.54: 6,
some_other_code = foo()
Copy the code
Python 3.9 runtime error message, difficult to locate the cause of the error:
>C: \ Users \ zioyi \. Pyenv \ pyenv - win \ versions \ 3.9.6 \ python exe syntax_error_1. Py
File "C:\Users\zioyi\python_code\syntax_error_1.py", line 3
some_other_code = foo()
^
SyntaxError: invalid syntax
Copy the code
Python 3.10’s error message is much nicer:
>C: \ Users \ zioyi \. Pyenv \ pyenv - win \ versions \ 3.10.0 b4 \ python exe syntax_error_1. Py
File "C:\Users\zioyi\python_code\syntax_error_1.py", line 1
expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
^
SyntaxError: '{' was never closed
Copy the code
- For syntax errors, the interpreter will
The highlighted
Displays the full range of errors that constitute syntax error codes
First look at Python 3.9:
>>> foo(x, z for z in range(10), t, w)
File "<stdin>", line 1
foo(x, z for z in range(10), t, w)
^
SyntaxError: Generator expression must be parenthesized
Copy the code
Look again at Python 3.10:
>>> foo(x, z for z in range(10), t, w)
File "<stdin>", line 1
foo(x, z for z in range(10), t, w)
^^^^^^^^^^^^^^^^^^^^
SyntaxError: Generator expression must be parenthesized
Copy the code
3. Error messages become more intelligent, not just ruthless judges who return SyntaxError: invalid syntax, but more like a teaching teacher
Let’s see what the teacher (Pyhton 3.10) tells us when we make mistakes
>>> # Forget to add colons to conditional statements
>>> if rocket.position > event_horizon
File "<stdin>", line 1
if rocket.position > event_horizon
^
SyntaxError: expected ':'
>>> # Unpack tuples without parentheses
>>> {x,y for x,y in zip('abcd'.'1234')}
File "<stdin>", line 1
{x,y for x,y in zip('abcd'.'1234')}
^
SyntaxError: did you forget parentheses around the comprehension target?
>>> # When constructing a dictionary, there is no comma between two elements
>>> items = {
.x: 1..y: 2
.z: 3,
File "<stdin>", line 3
y: 2
^
SyntaxError: invalid syntax. Perhaps you forgot a comma?
>>> # Prepare to replenish multiple exceptions, but write less parentheses
>>> try:
. build_dyson_sphere()
.except NotEnoughScienceError, NotEnoughResourcesError:
File "<stdin>", line 3
except NotEnoughScienceError, NotEnoughResourcesError:
^
SyntaxError: multiple exception types must be parenthesized
Copy the code
IndentationErrors
Indenting errors now have more context information about the type of block to be indented, including the position of the statement:
>>> def foo() :
. if lel:
. x = 2
File "<stdin>", line 3
x = 2
^
IndentationError: expected an indented block after 'if' statement in line 2
Copy the code
AttributeErrors
When a familiar error occurs, the PyErr_Display function will guess what you like and print out the property you might want:
>>> collections.namedtoplo
Traceback (most recent call last):
File "<stdin>", line 1.in <module>
AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?
Copy the code
NameErrors
As with property errors, when a naming error occurs, PyErr_Display will guess what you like and print out the variable name you might want:
>>> schwarzschild_black_hole = None
>>> schwarschild_black_hole
Traceback (most recent call last):
File "<stdin>", line 1.in <module>
NameError: name 'schwarschild_black_hole' is not defined. Did you mean: schwarzschild_black_hole?
Copy the code
PyErr_Display is a really sensible function
switch-caseMatch-case is finally here
Others (Java, Golang, C) have it, you (Pyhton) will have it, and only better! In response to the outcry, the Python version of Switch-Case, or Match-case, has finally arrived, and is one of the most notable features in Python 3.10
grammar
In the Python version of switch-Case, you write it in this format:
match subject:
case <pattern_1>:
<action_1>
case <pattern_2>:
<action_2>
case <pattern_3>:
<action_3>
case _:
<action_wildcard>
Copy the code
Simple matching
Before we had match-case, we wrote:
def http_error_if_else(status) :
if status == 400:
return "Bad request"
elif status == 404:
return "Not found"
elif status == 418:
return "I'm a teapot"
else:
return "Something's wrong with the internet"
# or so
def http_error_dict(status) :
http_status_to_error = {
400: "Bad request".404: "Not found".418: "I'm a teapot"
}
return http_status_to_error.get(status, "Something's wrong with the internet")
Copy the code
We know that if-else is not as good in terms of performance and readability as switch-case. Looking at Python 3.10, we can write:
def http_error_match_case(status) :
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the internet"
Copy the code
That’s a lot easier
You can also at the back of the case by using | series multiple, like this:
case 401 | 403 | 404:
return "Not allowed"
Copy the code
If you do not use _ pocket in a case statement, there may be no match. If no match exists, the behavior is an empty operation. For example, if state 500 is passed, a null operation occurs.
Match both variables and constants
When matching, the subject is transformed according to the pattern after the case to bind variables in pattern. In this example, a data point can be unpacked into its x and y coordinates:
# point is an (x, y) tuple
match point:
case (0.0) :print("Origin")
case (0, y):
print(f"Y={y}")
case (x, 0) :print(f"X={x}")
case (x, y):
print(f"X={x}, Y={y}")
case _:
raise ValueError("Not a point")
Copy the code