Python 3.9’s New Features: A Critical Look at Unnecessary Bloat
The article argues that Python 3.9’s recent additions—static type checking, variable annotations, extended operators, new string methods, and other syntactic sugar—contradict the language’s original philosophy of simplicity and elegance, turning Python into a heavier, less readable tool for developers.
Python 3.9 was officially released and quickly promoted by many IT platforms and media outlets, but most programmers feel indifferent or even hostile toward the new features, seeing them as raising the learning barrier for newcomers.
Superficial Static Type Checking
Since Python 3.5 the language team has pushed static type checking through the typing module and tools such as mypy , pylint , and pyflakes . The author questions the need for static checks in a dynamic language, arguing that they add unnecessary complexity and serve IDE vanity rather than Python’s core goal of solving problems with minimal fuss.
Redundant Variable Type Declarations
Example code shows a seasoned Python developer’s reaction to explicit type declarations:
<code>>> name: str
>> age: int = 18
>> gilrfriends: list = ['Audrey Hepburn', 'Camilla Belle', 'Angelina Jolie']
</code>The author points out that such annotations do not affect runtime behavior; the interpreter still accepts mismatched assignments without warnings, making the practice a needless concession to static analysis tools.
Useless Function and Parameter Annotations
Even with detailed docstrings, many developers still resort to assert statements for runtime validation. The article contrasts a hand‑written function with one that uses full type hints:
<code>def sphere(center, radius, color, slices=90):
"""Draw a sphere
center – tuple/list of length 3
radius – float
color – string
slices – int (higher = finer)
"""
assert isinstance(center, (tuple, list)) and len(center) == 3, 'center must be a 3‑element tuple or list'
print('Hello')
return True
from typing import Union
def sphere(center: Union[tuple, list], radius: float, color: str, slices: int = 90) -> bool:
"""Draw a sphere
center – tuple/list of length 3
radius – float
color – string
slices – int (higher = finer)
"""
print('Hello')
return True
</code>The annotated version looks cleaner but provides no runtime checks; it merely adds visual noise and can even hide bugs.
Unnecessary Dictionary Operators
Python 3.9 introduced the | (merge) and |= (update) operators for dictionaries, which duplicate the existing dict.update() method:
<code>a = {'x': 1, 'y': 2}
b = {'y': 3, 'z': 4}
a | b # returns a new dict
a |= b # updates a in place
</code>The author argues that the same effect can be achieved with the classic expression {**a, **b} , making the new operators redundant.
Bloated String Methods
Python 3.9 added str.removeprefix() and str.removesuffix() . While useful, the author warns that proliferating such one‑line helpers inflates the str API and shifts trivial tasks from developers to the language itself.
<code>s = '[Host] Goal (1:1)'
s.removeprefix('[Host]') # 'Goal (1:1)'
s.removesuffix('(1:1)') # '[Host] Goal '
</code>Confusing f‑String Enhancements
Python 3.8 introduced the = specifier inside f‑strings, turning them into a quasi‑assignment operator:
<code>score = 1
print(f'Current score {score=}') # 'Current score score=1'
</code>The author finds this syntax obscure and detrimental to readability.
Dictionary Order Misconception
Python 3.7 officially guaranteed insertion order for dictionaries, but the author stresses that order is an implementation detail, not a language guarantee, and should not be relied upon for program logic.
Function Parameter Separator (/)
Python 3.8 added the / marker to separate positional‑only parameters from others, further complicating function signatures:
<code>def func(a, b, /, c, d, *, e, f):
print('OK')
</code>The author deems this feature unnecessary for most Python code.
Generic Functions via singledispatch
Python 3.4 introduced functools.singledispatch to emulate generic functions, but the resulting code is verbose compared to simple isinstance checks.
<code>from functools import singledispatch
@singledispatch
def say_hello(x):
print('Sorry, I don\'t know you')
@say_hello.register(int)
def _(x):
print('Hello, integer')
@say_hello.register(str)
def _(x):
print('Hello, string')
</code>Overall, the article concludes that many of Python 3.9’s additions prioritize superficial features and IDE integration over the language’s original goals of simplicity, readability, and practicality.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.