Powerful Python Features
Hidden Python Features Every Developer Should Know

I am a python developer who is living and breathing python for last one and half year. My daily words revolves around python…from writing automation script, building data pipelines, performing data analysis, and optimizing workflows...python has been my go to languae for everything.
Over a time I realized python has many features that many developers don’t use often, but once you discovered them you will never go back.
So in this post I am sharing some crazy features of python.
1 — logging — For logs
print() is great for small scripts, but logging is made for professionals.
import logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
logging.info("Processing started")
logging.warning("Low memory")
logging.error("Something went wrong")
You can even log to files, rotate logs, or set custom log levels.
2 — argparse — Command Line Tools
If your script takes command-line arguments, argparse is your best friend.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--name", required=True, help="Your name")
args = parser.parse_args()
print(f"Hello {args.name}!")
Now your script supports:
python script.py --name Dipak
3 — asyncio — Asynchronous Python
Python is synchronous by default — it executes code line by line.
But with asyncio, you can run tasks concurrently and speed up I/O-bound processes like API calls or database requests.
import asyncio
async def fetch_data(id):
print(f"Fetching {id}")
await asyncio.sleep(1)
print(f"Done {id}")
async def main():
await asyncio.gather(fetch_data(1), fetch_data(2), fetch_data(3))
asyncio.run(main())
Output: All three fetches happen at once.
4 — threading — Run Tasks Simultaneously
If you’re dealing with multiple I/O-heavy tasks, threading can save time.
import threading, time
def task(name):
print(f"{name} started")
time.sleep(2)
print(f"{name} done")
threads = [threading.Thread(target=task, args=(f"Task {i}",)) for i in range(3)]
[t.start() for t in threads]
[t.join() for t in threads]
5 — Destructuring
You can unpack lists, tuples, and even dicts easily.
user = ("Dipak", "Developer", "India")
name, role, country = user
print(f"{name} is a {role} from {country}")
Partial unpacking works too:
a, *b = [1, 2, 3, 4, 5]
print(a, b) # 1 [2, 3, 4, 5]
6 — Walrus Operator
Assign values and use them instantly — perfect for short expressions.
if (n := len("Python")) > 4:
print(f"Length is {n}")
7 — f Strings
name = "Dipak"
print(f"Hello {name.upper()}! {2 + 3 = }")
You can do calculations, call functions, or even format dates inside f-strings.
8 — Pattern Matching (match Statement)
Introduced in Python 3.10, this is like a smarter switch-case.
def http_status(code):
match code:
case 200:
return "OK"
case 404:
return "Not Found"
case 500:
return "Server Error"
case _:
return "Unknown"
9 — Type Hints
def add(a: int, b: int) -> int:
return a + b
Even though Python doesn’t enforce them, type hints make code clearer and easier to maintain.
10 — yield and Generators
def count_up_to(n):
for i in range(n):
yield i
for num in count_up_to(5):
print(num)
Generators don’t load all data into memory — perfect for streams or large files.
11 — dataclasses — No More Boilerplate
from dataclasses import dataclass
@dataclass
class User:
name: str
age: int
active: bool = True
print(User("Dipak", 25))
12 — functools — Hidden Functional Superpowers
lru_cachecaches function results.reduceapplies a function cumulatively.partialcreates functions with pre-filled args.
from functools import lru_cache
@lru_cache
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
print(fib(10))
13 — itertools — Efficient Iteration Tools
import itertools
for pair in itertools.permutations([1, 2, 3], 2):
print(pair)
You also get chain(), combinations(), cycle(), and islice() — perfect for advanced loops.
14 — Context Managers (with, contextlib)
Automatically manage resources.
with open("data.txt") as f:
data = f.read()
Or make your own:
from contextlib import contextmanager
@contextmanager
def demo():
print("Start")
yield
print("End")
with demo():
print("Inside block")
15 — __slots__ — Memory Optimization Trick
Prevents dynamic attribute creation.
class Point:
__slots__ = ['x', 'y']
def __init__(self, x, y):
self.x, self.y = x, y
16 — enumerate() and zip() — Loop Like a Pro
for i, name in enumerate(["Dipak", "Shruti", "Hemant"], start=1):
print(i, name)
for a, b in zip([1, 2, 3], ['a', 'b', 'c']):
print(a, b)
17 — Comprehensions — One-Liner Magic
squares = [x**2 for x in range(10)]
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
unique = {ch for ch in "hello world"}
18 — subprocess — Run System Commands Safely
Instead of os.system(), use subprocess for more control.
import subprocess
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)
You can automate shell tasks, trigger other scripts, or capture outputs cleanly.
19 — pathlib — Modern File Path Handling
Forget about os.path.
from pathlib import Path
path = Path("data.txt")
if path.exists():
print(path.read_text())
It’s object-oriented, safer, and cleaner.
20 — collections — Smarter Data Structures
from collections import Counter, defaultdict, namedtuple
# Count frequencies
print(Counter("abracadabra"))
# Defaultdict with default type
d = defaultdict(list)
d["a"].append(1)
print(d)
# Namedtuple
Point = namedtuple("Point", "x y")
print(Point(1, 2))
21 — Dunder Methods — The Secret Power Behind Python
Make your classes behave like built-ins.
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
print(Vector(1, 2) + Vector(3, 4))
Conclusion —
After using Python daily for over 1.5 years, I can confidently say —
“Python isn’t just a language. It’s an entire ecosystem waiting to be explored.”
From asyncio to argparse, and from logging to yield, these hidden features make Python incredibly powerful and fun to use.
If you haven’t explored these yet — now’s the time.


