What Is New in Python 3.4
Python 3.4 was released on March 16, 2014. The biggest additions are the asyncio module (the event loop and coroutine infrastructure that later became central to Python's async story), pathlib for object-oriented filesystem paths, enum for enumeration types, and statistics for basic descriptive statistics. CPython also gained a pip bundled by default and improved importlib.
| Category | Change | PEP / Reference |
|---|---|---|
| New Modules | asyncio -- event loop, coroutines, futures, transports |
PEP 3156 |
| New Modules | enum -- enumeration types |
PEP 435 |
| New Modules | pathlib -- object-oriented filesystem paths |
PEP 428 |
| New Modules | statistics -- mean, median, stdev, variance |
PEP 450 |
| New Modules | tracemalloc -- trace memory allocations |
PEP 454 |
| New Modules | selectors -- high-level I/O multiplexing |
-- |
| Standard Library | pip bundled with CPython installer by default | PEP 453 |
| Standard Library | Overhauled importlib -- full implementation of import system |
PEP 302, PEP 328 |
| Security | Improved SSL/TLS defaults -- hostname checking on by default, weak ciphers removed | PEP 466 |
| Performance | Faster Unicode decoding; pickle protocol 4 |
-- |
asyncio -- Python's Async Foundation (PEP 3156)
The asyncio module landed in 3.4 as a provisional module. It brought an event loop, coroutine support (via yield from -- the await syntax came in 3.5), Future objects, and a transport/protocol framework for network code. This was the module that made Python a credible async platform.
import asyncio
@asyncio.coroutine
def greet_after(delay, name):
yield from asyncio.sleep(delay)
print(f"Hello, {name}")
loop = asyncio.get_event_loop()
loop.run_until_complete(greet_after(1.0, "World"))
loop.close()
In practice, 3.4's asyncio was provisional and somewhat verbose. The real productivity gains came with the async/await keywords in 3.5 and the API cleanup in 3.7 (asyncio.run()).
pathlib -- Object-Oriented Paths (PEP 428)
pathlib.Path represents filesystem paths as objects with methods, replacing the fragmented os.path string functions. You can join paths with /, read and write files with methods, and traverse directories with a clean API.
from pathlib import Path
p = Path("/etc") / "hosts"
print(p.exists()) # True
print(p.read_text()) # file contents
data_dir = Path("data")
for csv in data_dir.glob("*.csv"):
print(csv.stem) # filename without extension
For any new code that does filesystem work, pathlib is the right starting point. The os.path family still works and is often faster for simple operations, but pathlib reads more clearly and handles edge cases more consistently.
enum -- Enumeration Types (PEP 435)
The enum module provides a way to define named constants with identity, comparison, and iteration support. It replaces the pattern of defining constants as bare integers or strings scattered at module level.
from enum import Enum, IntEnum, auto
class Status(Enum):
PENDING = auto()
RUNNING = auto()
DONE = auto()
FAILED = auto()
print(Status.RUNNING.name) # "RUNNING"
print(Status.RUNNING.value) # 2
print(Status["DONE"]) # Status.DONE
class Permission(IntEnum):
READ = 4
WRITE = 2
EXECUTE = 1
Other Notable Additions in Python 3.4
- statistics module:
mean(),median(),mode(),stdev(),variance()-- basic stats without numpy. - tracemalloc: Memory allocation tracing to find leaks and hot allocators.
tracemalloc.start()begins tracing;tracemalloc.take_snapshot()captures a point-in-time view. - pip bundled: CPython installer now ships
pipby default (ensurepipmodule). No more bootstrapping pip separately after installation. - Pickle protocol 4: Supports very large objects (over 4 GiB), strings longer than 232 bytes, and uses more efficient opcodes for common types.
- SSL improvements: Hostname checking enabled by default; SSLv2 and SSLv3 disabled; RC4 ciphers removed.
- codecs.open() deprecation path:
io.open()is now the preferred way to open text files with specific encoding.
FAQ
Is asyncio in Python 3.4 stable enough for production?
The 3.4 asyncio was marked provisional -- the API was expected to change, and it did. The provisional status was lifted in 3.6. For production use, 3.7+ is recommended: asyncio.run() and native async/await syntax make it far more usable and the edge cases around event loop management are handled correctly.
Should I use pathlib or os.path?
Prefer pathlib for all new code. Most stdlib functions since 3.6 accept Path objects directly where they previously only accepted strings. The os.path functions are still there and useful for simple joins, but pathlib wins on readability and cross-platform correctness.
Can enum members be compared with == to their values?
Only with IntEnum. A standard Enum member is not equal to its integer value by design -- Status.RUNNING == 2 is False. If you need integer interoperability (e.g., for database comparisons), use IntEnum.
Does tracemalloc slow down production code significantly?
Yes -- tracing every allocation has overhead, typically 50-100% slowdown depending on allocation rate. Run it in development or staging to locate leaks, not in production unless you have a specific incident to diagnose.
What is the difference between statistics.mean() and sum()/len()?
For pure integer or float inputs they give the same value, but statistics.mean() returns a fraction when given integers, which preserves precision. It also handles Decimal and Fraction inputs correctly. sum()/len() with integers gives a float that can lose precision for large lists.