Hidden gems, native features, and tricks that will blow your mind 🚀
# The Walrus Operator := (Python 3.8+)
# Assign values inside expressions!
# Before: Repetitive
data = fetch_data()
if data:
process(data)
# After: Clean and efficient
if (data := fetch_data()):
process(data)
# Great for while loops
while (line := file.readline()):
print(f"Processing: {line.strip()}")
# List comprehensions with conditions
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Get squares of even numbers > 25
squares = [sq for n in numbers if (sq := n**2) > 25]
print(squares) # [36, 49, 64, 81, 100]
# Avoid repeated expensive calls
import re
# Bad: regex compiled twice
if re.match(r'^[a-z]+$', text) and len(re.match(r'^[a-z]+$', text).group()) > 5:
...
# Good: regex compiled once
if (m := re.match(r'^[a-z]+$', text)) and len(m.group()) > 5:
...
# Debug with inline assignments
data = [1, 2, 3, 4, 5]
result = [print(f"Processing {x}") or x**2 for x in data if (squared := x**2) and print(f"Squared: {squared}") or squared > 10]
Reduces code duplication and makes expressions more readable
Assign and use values in the same expression
// Format numbers for any locale
const num = 123456.789;
console.log(new Intl.NumberFormat('de-DE').format(num)); // 123.456,789
console.log(new Intl.NumberFormat('en-IN').format(num)); // 1,23,456.789
console.log(new Intl.NumberFormat('ar-EG').format(num)); // ١٢٣٬٤٥٦٫٧٨٩
// Currency formatting
const price = 123456.789;
console.log(new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(price)); // $123,456.79
console.log(new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY'
}).format(price)); // ¥123,457
// Relative time formatting
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // yesterday
console.log(rtf.format(2, 'hour')); // in 2 hours
console.log(rtf.format(-3, 'month')); // 3 months ago
// List formatting
const list = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
console.log(list.format(['Apple', 'Orange', 'Banana'])); // Apple, Orange, and Banana
// Plural rules
const pr = new Intl.PluralRules('pl');
const plurals = [0, 1, 2, 5, 21, 22, 25];
plurals.forEach(n => {
console.log(`${n}: ${pr.select(n)}`);
});
// Date/Time formatting with options
const date = new Date('2024-03-15T10:30:00');
console.log(new Intl.DateTimeFormat('en-US', {
dateStyle: 'full',
timeStyle: 'short'
}).format(date)); // Friday, March 15, 2024 at 10:30 AM
Native internationalization without any libraries
Handles complex pluralization rules for all languages
from dataclasses import dataclass, field, asdict, astuple, replace
from typing import List, Optional
import json
# Basic dataclass with defaults
@dataclass
class Point:
x: float
y: float = 0.0
def distance_from_origin(self) -> float:
return (self.x ** 2 + self.y ** 2) ** 0.5
# Advanced features
@dataclass(frozen=True) # Immutable
class FrozenPoint:
x: float
y: float
@dataclass(order=True) # Comparable
class Person:
sort_index: int = field(init=False, repr=False)
name: str
age: int
tags: List[str] = field(default_factory=list)
def __post_init__(self):
self.sort_index = self.age
# Use field() for mutable defaults
@dataclass
class Team:
name: str
members: List[Person] = field(default_factory=list)
metadata: dict = field(default_factory=lambda: {"created": "today"})
# Convert to/from dict
person = Person(name="Alice", age=30, tags=["python", "data"])
print(asdict(person)) # {'name': 'Alice', 'age': 30, 'tags': ['python', 'data']}
print(astuple(person)) # (30, 'Alice', 30, ['python', 'data'])
# Create modified copies
person2 = replace(person, age=31)
print(person2) # Person(name='Alice', age=31, tags=['python', 'data'])
# JSON serialization
@dataclass
class JsonSerializable:
name: str
value: float
def to_json(self):
return json.dumps(asdict(self))
@classmethod
def from_json(cls, json_str):
return cls(**json.loads(json_str))
# Inheritance
@dataclass
class Employee(Person):
employee_id: str
department: str = "Engineering"
Eliminates boilerplate code for classes
Automatic __init__, __repr__, __eq__ and more
// Create reactive objects
function reactive(target) {
const handlers = [];
return new Proxy(target, {
get(obj, prop) {
return obj[prop];
},
set(obj, prop, value) {
obj[prop] = value;
handlers.forEach(handler => handler(prop, value));
return true;
},
subscribe(handler) {
handlers.push(handler);
}
});
}
// Auto-calculate properties
const autoCalc = new Proxy({}, {
get(target, prop) {
if (prop === 'area' && 'width' in target && 'height' in target) {
return target.width * target.height;
}
return target[prop];
}
});
autoCalc.width = 10;
autoCalc.height = 20;
console.log(autoCalc.area); // 200
// Array with negative indexing (like Python!)
const negativeArray = arr => new Proxy(arr, {
get(target, prop) {
if (!isNaN(prop)) {
const index = Number(prop);
return target[index < 0 ? target.length + index : index];
}
return target[prop];
}
});
const arr = negativeArray([1, 2, 3, 4, 5]);
console.log(arr[-1]); // 5
console.log(arr[-2]); // 4
// Object with default values
const withDefaults = (obj, defaults) => new Proxy(obj, {
get(target, prop) {
return prop in target ? target[prop] : defaults[prop];
}
});
const config = withDefaults({}, {
host: 'localhost',
port: 3000,
debug: false
});
console.log(config.host); // 'localhost'
config.host = 'example.com';
console.log(config.host); // 'example.com'
// Validation proxy
const validated = (target, validator) => new Proxy(target, {
set(obj, prop, value) {
if (validator[prop] && !validator[prop](value)) {
throw new Error(`Invalid value for ${prop}: ${value}`);
}
obj[prop] = value;
return true;
}
});
const user = validated({}, {
age: v => v > 0 && v < 150,
email: v => /^[^@]+@[^@]+.[^@]+$/.test(v)
});
Intercept and customize object operations
Build reactive systems with vanilla JavaScript
from contextlib import contextmanager, suppress, redirect_stdout, ExitStack
import os
import sys
from io import StringIO
# Create context managers with @contextmanager
@contextmanager
def timed_operation(name):
import time
print(f"Starting {name}...")
start = time.time()
try:
yield
finally:
end = time.time()
print(f"{name} took {end - start:.3f} seconds")
# Use it
with timed_operation("data processing"):
# Simulate work
sum(i**2 for i in range(1000000))
# Suppress exceptions elegantly
with suppress(FileNotFoundError):
os.remove('non_existent_file.txt') # No error!
# Redirect output
f = StringIO()
with redirect_stdout(f):
print("This goes to StringIO")
print("So does this")
output = f.getvalue()
print(f"Captured: {output}")
# Multiple context managers dynamically
with ExitStack() as stack:
files = [
stack.enter_context(open(f'file{i}.txt', 'w'))
for i in range(3)
]
# All files will be properly closed
# Create a multi-purpose context manager
class DatabaseConnection:
def __init__(self, host):
self.host = host
self.connection = None
def __enter__(self):
print(f"Connecting to {self.host}")
self.connection = f"Connection to {self.host}"
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"Closing connection to {self.host}")
if exc_type:
print(f"Error occurred: {exc_val}")
# Return True to suppress exception
return False
def query(self, sql):
return f"Results from: {sql}"
# Temporary directory context
import tempfile
import shutil
@contextmanager
def temp_dir():
temp = tempfile.mkdtemp()
try:
yield temp
finally:
shutil.rmtree(temp)
with temp_dir() as td:
print(f"Working in {td}")
# Directory is automatically cleaned up
Manage resources and execution contexts elegantly
Create custom context managers in seconds
// Infinite sequences
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fib = fibonacci();
console.log(fib.next().value); // 0
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
// Take first n from any generator
function* take(n, iterable) {
let i = 0;
for (const value of iterable) {
if (i++ >= n) return;
yield value;
}
}
console.log([...take(10, fibonacci())]); // [0,1,1,2,3,5,8,13,21,34]
// Async generators for streams
async function* fetchPages(url, maxPages = 10) {
for (let page = 1; page <= maxPages; page++) {
const response = await fetch(`${url}?page=${page}`);
const data = await response.json();
if (data.items.length === 0) return;
for (const item of data.items) {
yield item;
}
}
}
// Use async generator
async function processAllItems() {
for await (const item of fetchPages('/api/items')) {
console.log('Processing:', item);
}
}
// Generator delegation
function* gen1() {
yield 1;
yield 2;
}
function* gen2() {
yield* gen1();
yield 3;
yield* [4, 5];
}
console.log([...gen2()]); // [1, 2, 3, 4, 5]
// Custom iterables
class Range {
constructor(start, end, step = 1) {
this.start = start;
this.end = end;
this.step = step;
}
*[Symbol.iterator]() {
for (let i = this.start; i <= this.end; i += this.step) {
yield i;
}
}
}
const range = new Range(1, 10, 2);
console.log([...range]); // [1, 3, 5, 7, 9]
// Two-way communication
function* twoWay() {
const input = yield 'Ready';
yield `You said: ${input}`;
}
const gen = twoWay();
console.log(gen.next().value); // 'Ready'
console.log(gen.next('Hello').value); // 'You said: Hello'
Handle infinite sequences and async streams elegantly
Lazy evaluation saves memory for large datasets
6 amazing features & tricks • 0 favorites saved
Made with and lots of 💜