惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
F
Fortinet All Blogs
B
Blog
GbyAI
GbyAI
P
Proofpoint News Feed
量子位
The Register - Security
The Register - Security
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
云风的 BLOG
云风的 BLOG
V
Visual Studio Blog
B
Blog RSS Feed
WordPress大学
WordPress大学
Recorded Future
Recorded Future
Recent Announcements
Recent Announcements
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Secure Thoughts
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Webroot Blog
Webroot Blog
AWS News Blog
AWS News Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The GitHub Blog
The GitHub Blog
爱范儿
爱范儿
O
OpenAI News
月光博客
月光博客
H
Hacker News: Front Page
S
Security Affairs
W
WeLiveSecurity
The Hacker News
The Hacker News
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
MongoDB | Blog
MongoDB | Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
Docker
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
Blog — PlanetScale
Blog — PlanetScale
J
Java Code Geeks
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
TaoSecurity Blog
TaoSecurity Blog
T
Threat Research - Cisco Blogs
M
MIT News - Artificial intelligence
A
About on SuperTechFans

Martin Heinz's Blog

A Guide to Python's Weak References Using weakref Module Recent Docker BuildKit Features You're Missing Out On Modern Git Commands and Features You Should Be Using Everything You Can Do with Python's textwrap Module Monitoring Indoor Air Quality with Prometheus, Grafana and a CO2 Sensor Everything You Can Do with Python's bisect Module You Don't Need a Dedicated Cache Service - PostgreSQL as a Cache A Collection of Docker Images To Solve All Your Debugging Needs Weird Python "Features" That Might Catch You By Surprise Lessons Learned From Writing 100 Articles Debugging Crashes and Deadlocks in Python using PyStack Goodbye etcd, Hello PostgreSQL: Running Kubernetes with an SQL Database Remote Interactive Debugging of Python Applications Running in Kubernetes The Right Way to Run Shell Commands From Python Real Multithreading is Coming to Python - Learn How You Can Use It Now Python's Missing Batteries: Essential Libraries You're Missing Out On Kubernetes-Native Synthetic Monitoring with Kuberhealthy Make Your CLI Demos a Breeze with Zero Stress and Zero Mistakes Reduce - The Power of a Single Python Function Why I Will Never Use Alpine Linux Ever Again Cgroups - Deep Dive into Resource Management in Kubernetes Dictionary Dispatch Pattern in Python Boost Your Python Application Performance using Continuous Profiling Lazy Evaluation Using Recursive Python Generators Python Magic Methods You Haven't Heard About Getting Started with Mastodon API in Python Backup-and-Restore of Containers with Kubernetes Checkpointing API Getting Started with Google APIs in Python Python CLI Tricks That Don't Require Any Code Whatsoever All The Ways To Introspect Python Objects at Runtime What is Python's "self" Argument, Anyway? Python List Comprehensions Are More Powerful Than You Might Think You Should Be Using Python's Walrus Operator - Here's Why Recipes and Tricks for Effective Structural Pattern Matching in Python It's Time to Say Goodbye to These Obsolete Python Libraries Advanced Features of Kubernetes' Horizontal Pod Autoscaler Data and System Visualization Tools That Will Boost Your Productivity Stop Messing with Kubernetes Finalizers Automate All the Boring Kubernetes Operations with Python End-to-End Monitoring with Grafana Cloud with Minimal Effort Bitly | bit.ly/3JLmSgA Bitly | bit.ly/3uETfbi Bitly | bit.ly/3MI4Iz0 Bitly | bit.ly/3M30D82 Bitly | bit.ly/3oMJ6qR Bitly | bit.ly/3IRD7IK Bitly | bit.ly/3A3B69t Bitly | bit.ly/31lKCYA Bitly | bit.ly/30uviIM Bitly | bit.ly/3E1X2mw Bitly | bit.ly/3Dv7JxP Bitly | bit.ly/3GG1BEz Bitly | bit.ly/3lLavs4 Bitly | bit.ly/39TqP3m Bitly | bit.ly/3A5Mpx8 Bitly | bit.ly/3kGwPl4 Bitly | bit.ly/3iHtulU Bitly | bit.ly/3xGjtKS Bitly | bit.ly/3h8DZg0 Bitly | bit.ly/2RQn1dG Bitly | bit.ly/3p2B5wW The Easiest Way to Debug Kubernetes Workloads Bitly | bit.ly/2PHVudx Cloud Native CI/CD with Tekton - Building Custom Tasks Bitly | bit.ly/3dg3QR9 Bitly | bit.ly/3qHtSkZ Deep Dive into Docker Internals - Union Filesystem Bitly | bit.ly/3qlRAUN Bitly | bit.ly/3pCUJ26 Bitly | bit.ly/3ifZxYr Bitly | bit.ly/34ZhIMt Bitly | bit.ly/3qSO7h0 Bitly | bit.ly/3muGLOk Bitly | bit.ly/35xN79v Bitly | bit.ly/3mLGshK Bitly | bit.ly/2IvkGQl Bitly | bit.ly/2Sk1KFK Bitly | bit.ly/3iCNIL6 Bitly | bit.ly/3beQPpy Saving Your Linux Machine from Certain Death Deploy Any Python Project to Kubernetes Analyzing Docker Image Security Recursive SQL Queries with PostgreSQL Automating Every Aspect of Your Python Project Tour of Python Itertools Implementing 2D Physics in Javascript Ultimate Setup for Your Next Python Project Making Python Programs Blazingly Fast Security and Cryptography Mistakes You Are Probably Doing All The Time Going Serverless with OpenFaaS and Golang - Building Optimized Templates Going Serverless with OpenFaaS and Golang - The Ultimate Setup and Workflow Setting Up Swagger Docs for Golang API Building RESTful APIs in Golang Pytest Features, That You Need in Your (Testing) Life Setting up GitHub Package Registry with Docker and Golang Ultimate Setup for Your Next Golang Project Python Tips and Trick, You Haven't Already Seen, Part 2. Tricks for Postgres and Docker that will make your life easier Getting The Most Out of Reading Books - Reading The "Professional Way" Python Tips and Trick, You Haven't Already Seen
New Features in Python 3.9 You Should Know About
Martin · 2020-04-26 · via Martin Heinz's Blog

Release of Python 3.9 is still quite a while away (5.10.2020), but with the last alpha (3.9.0a5) release out and first beta in near future, it feels like it's time to see what new features, improvements and fixes we can expect and look forward to. This article won't be an exhaustive list of every change, but rather a list of the most interesting and noteworthy things to come with next version for us - developers. So, let's dive in!

Installing Beta Version

To be able to actually try anything contained in the alpha/beta versions of Python 3.9, we first need to install it. Ideally alongside our existing Python 3.8 (or other stable version) installation, so that we don't mess up our default interpreter. So, to install the latest, greatest version:


wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0a5.tgz
tar xzvf Python-3.9.0a5.tgz
cd Python-3.9.0a5
./configure --prefix=$HOME/python-3.9.0a5
make
make install
$HOME/python-3.9.0a5/bin/python3.9

After running this you should be greeted by IDLE and message like:


Python 3.9.0a5 (default, Apr 16 2020, 18:57:58)
[GCC 9.2.1 20191008] on linux
Type "help", "copyright", "credits" or "license" for more information.

New Dict Operators

The most notable new feature is probably the new dictionary merging operator - | or |=. Until now, you would have to chose from one of the following 3 options for merging dictionaries:


# Dictionaries to be merged:
d1 = {"x": 1, "y": 4, "z": 10}
d2 = {"a": 7, "b": 9, "x": 5}

# Expected output after merging
{'x': 5, 'y': 4, 'z': 10, 'a': 7, 'b': 9}
# ^^^^^ Notice that "x" got overridden by value from second dictionary

# 1. Option
d = dict(d1, **d2)

# 2. Option
d = d1.copy()  # Copy the first dictionary
d.update(d2)   # Update it "in-place" with second one

# 3. Option
d = {**d1, **d2}

First option above uses dict(iterable, **kwargs) function which initializes dictionaries - first argument is normal dictionary and second one is list of key/value pairs, in this case it's just another dictionary unpacked using ** operator.

Second approach uses update function to update first dictionary with pairs from the second one. As this one modifies dictionary in-place, we need to copy the first one into final variable to avoid modifying the original.

Third - last - and in my opinion, the cleanest solution is to use dictionary unpacking and unpack both variables (d1 and d2) into the resulting one d.

Even though the options above are completely valid, we now have new (and better?) solution using | operator.


# Normal merging
d = d1 | d2
# d = {'x': 5, 'y': 4, 'z': 10, 'a': 7, 'b': 9}

# In-place merging
d1 |= d2
# d1 = {'x': 5, 'y': 4, 'z': 10, 'a': 7, 'b': 9}

First example above does very much the same as operator unpacking shown previously (d = {**d1, **d2}). The second example on the other hand can be used for in-place merging, where original variable (d1) is updated with values from second operand (d2).

Topological Ordering

Next new interesting (and little obscure) feature is part of functools module. You can find it under TopologicalSorter class. This class allows us to sort graphs using topological ordering. What is that? you may ask. Topological ordering is such ordering where for 2 nodes u and v connected by directed edge uv (from u to v), u comes before v.

Before introduction of this feature, you would have to implement it yourself using e.g. Khan's algorithm or depth-first search which aren't exactly simple algorithms. So, now in case need to - for example - sort dependant jobs for scheduling, you just do the following:


from functools import TopologicalSorter
graph = {"A": {"D"}, "B": {"D"}, "C": {"E", "H"}, "D": {"F", "G", "H"}, "E": {"G"}}
ts = TopologicalSorter(graph)
list(ts.static_order())
# ['H', 'F', 'G', 'D', 'E', 'A', 'B', 'C']

Directed Graph In example above we first create graph using dictionary, where keys are outgoing nodes and values are sets of their neighbours. After that we create instance of sorter using our graph and then call static_order function to produce the ordering. Bear in mind that this ordering may depend on order of insertion, because when 2 nodes are in same level of graph, they are going to be returned in the order they were inserted in.

Apart from static ordering, this class also supports parallel processing of nodes as they become ready for processing, which is useful when working with e.g. task queues - you can find example of that in Python library docs here.

IPv6 Scoped Addresses

Another change introduced in Python 3.9 is ability to specify scope of IPv6 addresses. In case you are not familiar with IPv6 scopes, they are used to specify in which part of the internet is the respective IP address valid. Scope can be specified at the end of IP address using % sign - for example: 3FFE:0:0:1:200:F8FF:FE75:50DF%2 - so this IP address is in scope 2 which is link-local address.

So, in case you need to deal with IPv6 addresses in Python, you can now do so like this:


from ipaddress import IPv6Address
addr = IPv6Address('ff02::fa51%1')
print(addr.scope_id)
# "1" - interface-local IP address

There is one thing you should be careful with when using IPv6 scopes though. Two addresses with different scopes are not equal when compared using basic Python operators.

New math Functions

Meanwhile in the math module, bunch of miscellaneous functions were added or improved. Starting with the improvement to one existing function:


import math

# Greatest common divisor
math.gcd(80, 64, 152)
# 8

Previously gcd function which calculates the Greatest Common Divisor could only be applied to 2 numbers, forcing programmers to do something like this math.gcd(80, math.gcd(64, 152)), when working with more numbers. Starting with Python 3.9, we can apply it to any number of values.

First new addition to math module is math.lcm function:


# Least common multiple
math.lcm(4, 8, 5)
# 40

math.lcm calculates Least Common Multiple of its arguments. Same as with GCD, it allows variable number of arguments.

The 2 remaining new functions are very much related. These are math.nextafter and math.ulp:


# Next float after 4 going towards 5
math.nextafter(4, 5)
4.000000000000001
# Next float after 9 going towards 0
math.nextafter(9, 0)
8.999999999999998

# Unit in the Last Place
math.ulp(1000000000000000)
0.125

math.ulp(3.14159265)
4.440892098500626e-16

The math.nextafter(x, y) function is pretty straightforward - it's next float after x going towards y while taking into consideration floating-point number precision.

The math.ulp on the other hand might look little weird... ULP stands for "Unit in the Last Place" and it's used as a measure of accuracy in numeric calculations. Shortest explanation is using an example:

Let's imagine that we don't have 64 bit computer. Instead, all we have is just 3 digits. With these 3 digits we can represent number like 3.14, but not 3.141. With 3.14, the nearest larger number that we can represent is 3.15, These 2 numbers differ by 1 ULP (Units at the last place), which is 0.1. So, what the math.ulp returns is equivalent of this example, but with actual precision of your computer. For proper example and explanation see nice writeup at https://matthew-brett.github.io/teaching/floating_error.html.

New String Functions

math module is not the only one that got some new functions. Two new convenience functions for strings were added too:


# Remove prefix
"someText".removeprefix("some")
# "Text"

# Remove suffix
"someText".removesuffix("Text")
# "some"

These 2 functions perform what you would otherwise achieve using string[len(prefix):] for prefix and string[:-len(suffix)] for suffix. These are very simple operations and therefore also very simple functions, but considering that you might perform these operations quite often, it's nice to have built-in function that does it for you.

Bonus: HTTP Codes

Last but not least, well actually... are HTTP status codes added to http.HTTPStatus. Namely those are:


import http

http.HTTPStatus.EARLY_HINTS
# <HTTPStatus.EARLY_HINTS: 103>

http.HTTPStatus.TOO_EARLY
# <HTTPStatus.TOO_EARLY: 425>

http.HTTPStatus.IM_A_TEAPOT
# <HTTPStatus.IM_A_TEAPOT: 418>

Looking at these status code, I can't quite see why would you ever use them. That said, it's great to finally have I'm a Teapot status code at our disposal. It's great quality of life improvement that I can now use http.HTTPStatus.IM_A_TEAPOT when returning this code from production server (sarcasm, Please never do that...).

Conclusion

Probably not all of these changes are relevant to your daily programming, but I think it's good to be at least aware of the first 2 additions (| operator and TopologicalSorter) as they might come in handy at some point. That said Python 3.9 is still in alpha phase, so there still might be some additional changes up until 18.5.2020 (first beta release). But even then you should not use this version, as it is not stable nor production ready (not at least until October).

Resources