Python 3.9 - Complexity & Features¶
Python 3.9 was released October 2020 with improved type hinting and optimizations.
Major Features¶
Type Hints Without Imports¶
# Python 3.9+: Use built-in types for type hints
def process(items: list[int]) -> dict[str, int]:
return {str(i): i for i in items}
# Before 3.9: Required imports
from typing import List, Dict
def process(items: List[int]) -> Dict[str, int]:
return {str(i): i for i in items}
Dictionary Operations¶
# Merge and update operators for dicts (PEP 584)
d1 = {'a': 1, 'b': 2}
d2 = {'c': 3}
# Merge (non-mutating)
d3 = d1 | d2 # {'a': 1, 'b': 2, 'c': 3}
# Update (mutating)
d1 |= d2 # d1 now {'a': 1, 'b': 2, 'c': 3}
# Same as:
# d3 = {**d1, **d2} (3.5+)
# d1.update(d2)
Flexible Function Decorators¶
# Can use expressions as decorators
buttons = [button1, button2, button3]
# Python 3.9: Cleaner syntax
@buttons[0].clicked.connect
def on_button_clicked():
pass
# Instead of:
# decorator = buttons[0].clicked.connect
# @decorator
# def on_button_clicked():
# pass
Performance Characteristics¶
Comparable to Python 3.8¶
Performance improvements modest from 3.8:
# 3.9 vs 3.8: Similar speed
# New features have minimal overhead
Complexity Unchanged¶
All data structure complexities same as 3.8:
| Type | Operation | Complexity |
|---|---|---|
| list | append | O(1) amortized |
| list | insert | O(n) |
| dict | lookup | O(1) avg |
| dict | insert | O(1) avg |
| set | add | O(1) amortized |
| str | find | O(n*m) |
Data Structure Examples¶
Dictionary Merge¶
# Union operator (|) for dicts
config_default = {
'timeout': 30,
'retries': 3,
'debug': False
}
config_user = {
'timeout': 60,
'debug': True
}
# Combine configs
config = config_default | config_user
# {'timeout': 60, 'retries': 3, 'debug': True}
# Same complexity as unpacking
# config = {**config_default, **config_user} # O(n+m)
List Type Hints¶
# Cleaner type hints
def process_numbers(nums: list[int]) -> list[int]:
"""Process a list of integers."""
return [n * 2 for n in nums]
def get_mapping(keys: list[str]) -> dict[str, int]:
"""Create mapping from keys."""
return {k: i for i, k in enumerate(keys)}
# More readable than typing.List, typing.Dict
Standard Library Changes¶
Graph Changes¶
ZoneInfo module for timezone support:
from zoneinfo import ZoneInfo
from datetime import datetime
# Better timezone handling
dt = datetime(2020, 10, 31, 12, tzinfo=ZoneInfo("America/Los_Angeles"))
Deprecations¶
Some modules marked for removal:
# These modules deprecated (removed in 3.11+):
# - aifc, audioop, chunk, cgi, cgitb, imaplib, mailcap
# - nis, nntplib, spwd, sunau, xdrlib
# Plan migrations if using these
Examples and Patterns¶
Pattern: Configuration Merge¶
# Pre-3.9: verbose
defaults = {'a': 1, 'b': 2}
overrides = {'b': 3, 'c': 4}
config = {**defaults, **overrides}
# 3.9+: cleaner
config = defaults | overrides # {'a': 1, 'b': 3, 'c': 4}
Pattern: Multiple Inheritance with MRO¶
Type hints improved for complex inheritance:
class Animal:
pass
class Flyer:
pass
class Bird(Animal, Flyer):
pass
def process(b: Bird) -> None:
pass
# Type hints clearer without importing from typing
Memory and Performance¶
String Changes¶
Python 3.9 optimized string representation:
# Flexible string representation (from 3.3) further optimized
s = "hello" # ASCII: 1 byte per char
s = "こんにちは" # Multi-byte: 2 bytes per char
# More efficient than 4-byte per char in older Python
Compatibility¶
Minimal Breaking Changes¶
Very safe upgrade from 3.8:
# Almost all code works unchanged
# New features are optional
# No major complexity changes
New in 3.9¶
# New features (optional):
# 1. Type hints without imports: list[int]
# 2. Dict merge: d1 | d2
# 3. Flexible function decorators
# 4. Better error messages
Recommendations¶
When to Use Python 3.9¶
Good for: - ✅ New projects (nice type hint syntax) - ✅ Long-term support (EOL October 2025) - ✅ Stable baseline (well-tested)
Better choices: - 3.11+ if performance critical - 3.10+ for pattern matching - 3.8 if compatibility paramount
Performance Considerations¶
Python 3.9 adequate for most workloads:
# Performance improvements over 3.8 modest
# Focus on algorithmic optimization first
# Upgrade to 3.11 if performance critical
Upgrade Path¶
From Python 3.8¶
# Test with 3.9
pyenv install 3.9.x
pyenv shell 3.9.x
pytest # Run tests
# Usually works without changes
# Update type hints to use new syntax (optional)
Code Updates (Optional)¶
# Old style (still works in 3.9+)
from typing import List, Dict
def func(items: List[int]) -> Dict[str, int]:
pass
# New style (preferred in 3.9+)
def func(items: list[int]) -> dict[str, int]:
pass
Related Documentation¶
- Python 3.10 - Pattern matching
- Python 3.11 - Performance improvements
- Python 3.8