! [](https://p6-tt-ipv6.byteimg.com/large/pgc-image/422bffde9f2749289b7506713fd8985f)

After a trial period of nearly a year, Python 3.9 was released as a stable release on October 5 (2020), meaning that no changes will be made until the next release, and that you can feel free to update it. After enjoying the National Day holiday, let’s take a look at the surprises brought by the new version

Here is a feature map compiled by a 16 year old Indian brother:

! [](https://p9-tt-ipv6.byteimg.com/large/pgc-image/3d5bf8bc8af94c5c80e640f1b7cc57ca)

Energy saving paper

The most exciting feature of this release is energy saving, not only saving power, but more importantly saving the number of times to type code, and our precious time

Dictionary merge and update

There is no doubt that a dictionary object (Dict) is commonly used in the daily programming to the data structure, from the key value to support complex algorithm, rely on the dictionary object, but some commonly used fields and update operations, although Python has provided field update method and dictionary of operator (* *), but still not enough concise, I understand, until you see the update in the new version, you won’t feel anything is not neat

Original merge:

D1 = {' a ':' a ', 'b', 'b', 'c', 'c'} d2 = {' d ':' d ', 'e', 'e'} d3 = {d1, * * * * d2} # use of an operator, will combine the results into d3 print (d3) # {' a ': 'A', 'b', 'b', 'c', 'c', 'd' : 'd', 'e', 'e'} d1. Update (d2) # update method, incorporating d1, d2, and update the d1 print (d1) # {' A ':' A ', 'b' : 'B', 'c': 'C', 'd': 'D', 'e': 'E'}Copy the code

Now merge:

D1 = {' a ':' a ', 'b', 'b', 'c', 'c'} d2 = {' d ':' d ', 'e', 'e'} # d3 = | d1 d2 effect is equivalent to an operator print (d3) # {' a ':' a ', 'b' : 'B', 'c', 'c', 'd' : 'd', 'e', 'e'} | = d1 d2 # is equal to the update print (d1) # {' a ':' a ', 'B', 'B', 'c', 'c', 'd' : 'd', 'e', 'e'}Copy the code
  • | operator, in addition to numerical and operation, can now do a dictionary object
  • | = if you want to use in front of the consolidated result update dictionary object, after the merge operator and number assignment

Isn’t it much simpler? Not only simpler, but easier to understand

It’s not all, merging assignment operator (| =) in addition to the merger between the dictionary, can also be combined class dictionary object

Let’s start with some code:

d1 = {'a': 'A', 'b': 'B', 'c': 'C'}

l1 = [('d', 'D'), ('e', 'E')]

d1 |= l1

print(d1)  # {'a': 'A', 'b': 'B', 'c': 'C', 'd': 'D', 'e': 'E'}
Copy the code
  • L1 is a list object whose elements are two-dimensional tuples
  • The special thing here is that when a two-dimensional tuple object is merged, the first element is treated as the dictionary’s Key and the second as the dictionary’s Value. Otherwise, an error is reported

If you have this particular scenario, merge operations are extremely convenient. Can you think of any similar scenarios? Welcome to leave a message

A topological sort

First of all, we need to understand what is a topology, which is simply the relationship between a number of points in a certain space. For example, for a job, there are several tasks, among which there are interdependent relations. Tasks and their relations constitute a topology structure

Topological sort is a sort of points in a topology according to their relationships

Take a topology like this

! [](https://p6-tt-ipv6.byteimg.com/large/pgc-image/d97a8f12da194b4e9020c781d0993fb8)

Topological ordering is

One, two, three, four, five

It would take more than ten lines to write algorithmically, and that doesn’t include time spent debugging and making improvements for various adaptations

Now, sorting takes only one line of code:

from graphlib import TopologicalSorter

tg = {5: {3, 4}, 4: {2, 3}, 3: {2, 1}, 2: {1}}
ts = TopologicalSorter(tg)

print(list(ts.static_order())) # [1, 2, 3, 4, 5]

static_order
Copy the code

In fact, at the heart of this is the code that creates sorted objects, and the new feature provides elegant encapsulation

Speaking of encapsulation, as you might guess, there is more to it than that. Indeed, the ordering component TopicalSorter can sort not only defined and defined results, but also dynamic structures, for example

from graphlib import TopologicalSorter

ts = TopologicalSorter()
ts.add(5, 3, 4)
ts.add(4, 2, 3)
ts.add(3, 2, 1)
ts.add(2, 1)

print(list(ts.static_order())) # [1, 2, 3, 4, 5]
Copy the code

That is, dependencies can be added gradually, which is convenient in the case of iterative processing,

Note that the static_order method can only be used once, and the TopologicalSorter object needs to be recreated to sort again

In addition, if the topology structure is cyclic, the sort will report a CycleError loop-dependent error

Random bytecode

In order to generate random bytecodes, you need to generate random numbers first, and then get the corresponding characters from the defined character sequence, and then convert them into bytes, which is quite troublesome. Now, one line of code is done

Import random print(random.randbytes(10)) # b'\x0fzf\x17K\x00\ XFB \x11LF' import random print(random.randbytes(10)) # b'\x0fzf\x17K\x00\ XFB \x11LFCopy the code

Least common multiple

The greatest common divisor has been implemented in previous Versions of Python. You can use the greatest common divisor to get the least common multiple, but it requires multiple lines of code (I actually don’t remember how to push it).

Now, one line of code is done:

import math
math.lcm(49, 14)  # 98
Copy the code

Is it more convenient? If you don’t believe it, compare it with the following:

def lcm(num1, num2):
  if num1 == num2 == 0:
    return 0
  return num1 * num2 // math.gcd(num1, num2)

lcm(49, 14)  # 98
Copy the code

Feature article

In terms of functionality, Python 3.9 has also made a number of improvements, which you’ll see below

String without prefix suffix

Strings are already powerful enough to manipulate in Python, and it’s hard to imagine that it would include the ability to remove prefixes and suffixes as an update, so let’s take a look

"three cool features in Python".removesuffix(" Python")
# three cool features in

"three cool features in Python".removeprefix("three ")
# cool features in Python

"three cool features in Python".removeprefix("Something else")
# three cool features in Python
Copy the code

It’s easy to think of other ways to do this without much code, such as using the string strip method:

"three cool features in Python".strip(" Python")
# ree cool features i
Copy the code

Obviously, the end result is not what we want, and Strip will trim the character patterns before and after!

Other methods, such as string lookup, re matching, etc., can also be implemented, but it is not as convenient as a ready-made method, and more importantly, this feature prevents you from accidentally making mistakes

Time zone support

Time zones are not a problem for us in China, especially for domestic applications, but they can be a problem in every, or anywhere else. Previously, it was possible to convert the time to UTC and then to another time zone, which can now be easily done with the ZoneInfo module

The ZoneInfo module introduces the IANA time zone database to the standard library

from zoneinfo import ZoneInfo
from datetime import datetime

dt = datetime(2020, 10, 1, 1, tzinfo= ZoneInfo("America/Los_Angeles"))
Copy the code

As shown in the code, you can set the time zone for the local time, converting the time to the time in the specified time zone

Note: Before using ZoneInfo to get the time zone properties, you need to install the tzData module

other

Data type hint

Python itself is a weakly typed language, but it is prone to introducing bugs in large projects because of data types. To improve this, we declare parameters for data types, and get warnings when executing if the actual participating parameters do not have the same type, for example

Def fun(input: STR): print(STR) fun(10) # def fun(input: STR): print(STR) fun(10Copy the code

More powerful parsers

Python 3.9 refactored the parser, and while it’s almost invisible in everyday programming, this update is the most important one, so if you’re feeling like you’re on the right track, someone is quietly paying for it

Python has previously used the LL(1) parser to parse source code into parse trees, similar to parsers that read the source code one character at a time and interpret it without backtracking.

The new interpreter was implemented based on PEG(Parsing expression Grammar), which was efficient and flexible, but required much more memory

The import() feature is modified

Import () In previous versions, it is possible to raise ValueError. The official explanation is that ValueError used to occur when a relative package was imported beyond its highest level (unintelligible). In the new version, it makes more sense to raise ImportError when an exception is raised

I haven’t come across it, so maybe I haven’t used it, so it’s just learning

conclusion

“Life is short, use my Python” — Python not only says this, but it also does this, and while we’re enjoying a nice double-holiday, Python quietly optimizes itself to make our short lives even better

What are you waiting for, just upgrade to Python3.9 and try

Complete project code acquisitionJust click here