Python
Python is a high-level, interpreted, general-purpose programming language known for its simplicity, readability, and versatility. It supports multiple paradigms, including object-oriented, procedural, and functional programming. Because of its clean syntax and rich ecosystem, Python is widely used in web development, data science, artificial intelligence, automation, and more.
History of Python
- Late 1980s – Developed by Guido van Rossum at Centrum Wiskunde & Informatica (CWI), Netherlands.
- 1991 – First public release: Python 0.9.0, which already included modules, exceptions, functions, and core data types (str, list, dict).
- Named after the British comedy series “Monty Python’s Flying Circus”, not the snake.
Major Python Versions & Key Features
Python 1.x (1991 – 2000)
- First stable release: Python 1.0 (1994).
- Key features: functions, exceptions, core data types, and modules.
- Early focus on extensibility and portability.
Python 2.x (2000 – 2020)
Released in 2000 with many improvements, but also some design flaws.
Major features:
- List comprehensions.
- Garbage collection via reference counting & cycles.
- Unicode support (limited in 2.x).
Python 2.7 (2010) became the last release in the 2.x line.
Official support ended on January 1, 2020.
Python 3.x (2008 – present)
Released in 2008, not backward-compatible with Python 2.
Major features and changes:
- print() function replaces
printstatement. - Unicode by default (all strings are Unicode).
- Integer division change:
/gives float,//gives integer. - Function annotations for better readability and typing support.
- Async/await keywords (introduced in Python 3.5).
- F-strings (formatted string literals, introduced in 3.6).
- Type hinting improvements (gradually added).
- Pattern matching (introduced in 3.10).
- Performance optimizations (especially in Python 3.11+).
- print() function replaces
Features
1. Print as a Function
# Python 3
print("Hello, World!")
# Python 2 (invalid in Python 3)
# print "Hello, World!"2. Unicode by Default
text = "こんにちは" # Japanese for "Hello"
print(text) # Strings are Unicode by default in Python 33. Integer Division Change
print(5 / 2) # 2.5 (float division)
print(5 // 2) # 2 (integer division)4. Function Annotations / Type Hints
def greet(name: str, age: int) -> str:
return f"Hello, {name}. You are {age} years old."
print(greet("Alice", 25))5. Generators with yield
def count_up_to(n):
i = 1
while i <= n:
yield i # Produces values one at a time
i += 1
for number in count_up_to(5):
print(number)6. Async / Await (Asynchronous Programming)
import asyncio
async def say_hello():
await asyncio.sleep(1)
print("Hello after 1 second")
asyncio.run(say_hello())7. F-Strings (Formatted String Literals)
name = "Alice"
age = 25
print(f"My name is {name} and I am {age} years old.")8. Improved Iteration with enumerate and zip
fruits = ["apple", "banana", "cherry"]
for i, fruit in enumerate(fruits, start=1):
print(i, fruit)
colors = ["red", "yellow", "purple"]
for fruit, color in zip(fruits, colors):
print(f"{fruit} is {color}")9. Unpacking in Assignments
a, b, *rest = [1, 2, 3, 4, 5]
print(a, b, rest) # 1 2 [3, 4, 5]10. Pattern Matching (Python 3.10+)
def match_example(value):
match value:
case 0:
return "Zero"
case 1 | 2:
return "One or Two"
case _:
return "Something else"
print(match_example(2)) # One or Two11. Walrus Operator (:=, Python 3.8+)
# Assignment inside expression
if (n := len("Python")) > 3:
print(f"Length is {n}")12. Dictionary Comprehensions
squares = {x: x*x for x in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}13. Set Comprehensions
unique = {x for x in "banana"}
print(unique) # {'a', 'n', 'b'}14. Context Managers (with)
with open("example.txt", "w") as f:
f.write("Hello, file!")15. Exception Handling with as
try:
1 / 0
except ZeroDivisionError as e:
print("Error:", e)16. Extended Iterable Unpacking (PEP 3132)
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last) # 1 [2, 3, 4] 517. Named Expressions in Loops
data = ["apple", "banana", "cherry"]
while (item := data.pop(0)) != "cherry":
print(item)18. Improved Performance in Recent Versions (3.11+)
Try running the following with older versions and with versions with 3.11+:
import time
# Example 1: Function calls (faster in 3.11+)
def add(a, b):
return a + b
def benchmark_func_calls(n=10_000_00):
for _ in range(n):
add(1, 2)
# Example 2: Exception handling (optimized in 3.11+)
def benchmark_exceptions(n=100_000):
for _ in range(n):
try:
raise ValueError("test")
except ValueError:
pass
# Example 3: Nested loops (general interpreter speedup)
def benchmark_loops(n=1_000_000):
s = 0
for i in range(n):
s += i
return s
# Run benchmarks
start = time.time()
benchmark_func_calls()
print("Function calls:", time.time() - start, "seconds")
start = time.time()
benchmark_exceptions()
print("Exceptions:", time.time() - start, "seconds")
start = time.time()
benchmark_loops()
print("Loops:", time.time() - start, "seconds")List comprehensions
1. Square numbers
squares = [x*x for x in range(5)]
print(squares) # [0, 1, 4, 9, 16]2. Filtering with a condition
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]3. Applying a function
words = ["hello", "world", "python"]
uppercased = [w.upper() for w in words]
print(uppercased) # ['HELLO', 'WORLD', 'PYTHON']4. Cartesian product
pairs = [(x, y) for x in [1, 2] for y in [3, 4]]
print(pairs) # [(1, 3), (1, 4), (2, 3), (2, 4)]5. Flatten a matrix
matrix = [[1, 2], [3, 4], [5, 6]]
flattened = [num for row in matrix for num in row]
print(flattened) # [1, 2, 3, 4, 5, 6]6. Inline if-else
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
print(labels) # ['even', 'odd', 'even', 'odd', 'even']7. Remove vowels from a string
text = "comprehension"
no_vowels = [ch for ch in text if ch not in "aeiou"]
print(no_vowels) # ['c', 'm', 'p', 'r', 'h', 'n', 's', 'n']8. Transpose a matrix
matrix = [[1, 2, 3], [4, 5, 6]]
transpose = [[row[i] for row in matrix] for i in range(3)]
print(transpose) # [[1, 4], [2, 5], [3, 6]]9. Set and Dictionary Comprehensions (related feature)
# Set comprehension
unique = {x % 3 for x in range(10)}
print(unique) # {0, 1, 2}
# Dict comprehension
squares_dict = {x: x*x for x in range(5)}
print(squares_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}Advanced Features
1. Decorators (Functions that modify other functions/classes)
def debug(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with {args} {kwargs}")
return func(*args, **kwargs)
return wrapper
@debug
def greet(name):
return f"Hello, {name}"
print(greet("Alice"))2. Generators and yield (Lazy evaluation, efficient iteration)
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
print(list(fibonacci(10)))3. Context Managers (with) & __enter__ / __exit__
class ManagedFile:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, "w")
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with ManagedFile("test.txt") as f:
f.write("Hello, world!")4. Metaclasses (Classes that create classes)
class Meta(type):
def __new__(cls, name, bases, dct):
print(f"Creating class {name}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=Meta):
pass5. Descriptors (Custom attribute access)
class Celsius:
def __get__(self, instance, owner):
return instance._celsius
def __set__(self, instance, value):
if value < -273.15:
raise ValueError("Temperature below absolute zero!")
instance._celsius = value
class Temperature:
celsius = Celsius()
t = Temperature()
t.celsius = 25
print(t.celsius) # 256. Coroutines (async / await)
import asyncio
async def main():
await asyncio.sleep(1)
print("Done after 1 second")
asyncio.run(main())7. Pattern Matching (Python 3.10+)
def handle(data):
match data:
case {"type": "error", "msg": msg}:
print(f"Error: {msg}")
case {"type": "success", "value": v}:
print(f"Success: {v}")
case _:
print("Unknown")
handle({"type": "error", "msg": "File not found"})8. Multiple Inheritance & MRO (Method Resolution Order)
class A:
def hello(self): print("A")
class B(A):
def hello(self): print("B")
class C(A):
def hello(self): print("C")
class D(B, C):
pass
D().hello() # B (follows MRO: D → B → C → A)
print(D.mro()) # Method Resolution Order9. Dynamic Code Execution (eval, exec)
code = "x = 5\ny = 10\nprint(x + y)"
exec(code) # Runs dynamically10. Property Decorator (@property)
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def area(self):
return 3.14 * self._radius ** 2
c = Circle(5)
print(c.area) # 78.511. Monkey Patching (Changing behavior at runtime)
class Person:
def say_hello(self):
print("Hello!")
def new_hello(self):
print("Hi there!")
Person.say_hello = new_hello
p = Person()
p.say_hello() # Hi there!12. Closures (Functions inside functions)
def multiplier(factor):
def inner(x):
return x * factor
return inner
double = multiplier(2)
print(double(5)) # 1013. Slots (__slots__) for Memory Optimization
class Point:
__slots__ = ("x", "y") # Prevents dict overhead
def __init__(self, x, y):
self.x, self.y = x, y
p = Point(1, 2)
print(p.x, p.y)14. Operator Overloading (__add__, __str__, etc.)
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 __str__(self):
return f"({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # (4, 6)Great question — Python is actually a very multi-paradigm language, meaning you’re not restricted to just one programming style. You already mentioned Aspect-Oriented, Object-Oriented, and Functional, but Python comfortably supports several others as well. Let’s go through them:
Supported Programming Paradigms
1. Imperative Programming
What it is: Writing step-by-step instructions that change the program state.
How Python supports it: Basic loops, conditionals, assignments (
for,while,if, etc.).Example:
pythontotal = 0 for i in range(5): total += i print(total)
2. Procedural Programming
What it is: A specialization of imperative programming, organizing code into reusable procedures (functions).
How Python supports it: Functions are first-class citizens.
Example:
pythondef add(a, b): return a + b print(add(2, 3))
3. Object-Oriented Programming (OOP)
What it is: Encapsulating data and behavior into classes and objects.
How Python supports it: Classes, inheritance, polymorphism, mixins, and even metaclasses.
Example:
pythonclass Animal: def speak(self): pass class Dog(Animal): def speak(self): return "Woof!"
4. Functional Programming (FP)
What it is: Treating computation as evaluation of pure functions, avoiding mutable state.
How Python supports it:
map,filter,reduce, comprehensions,lambda,functools.Example:
pythonfrom functools import reduce nums = [1, 2, 3, 4] print(reduce(lambda x, y: x + y, nums))
5. Aspect-Oriented Programming (AOP)
What it is: Separating cross-cutting concerns (logging, security, transactions).
How Python supports it: Not native, but achievable with decorators, metaprogramming, or libraries like
aspectlib.Example (logging decorator):
pythondef log(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}") return func(*args, **kwargs) return wrapper @log def greet(name): return f"Hello, {name}!"
6. Declarative Programming
What it is: Describing what the program should accomplish, not how.
How Python supports it: DSLs, SQLAlchemy for ORM, configuration via data structures.
Example:
pythonfrom sqlalchemy import Table, Column, Integer, String, MetaData metadata = MetaData() users = Table("users", metadata, Column("id", Integer, primary_key=True), Column("name", String))
7. Metaprogramming
What it is: Code that manipulates code (introspection, modifying classes/functions at runtime).
How Python supports it:
type(),metaclass,inspect, decorators.Example:
pythonclass Meta(type): def __new__(cls, name, bases, dct): dct["created_by"] = "Meta" return super().__new__(cls, name, bases, dct) class MyClass(metaclass=Meta): pass print(MyClass.created_by)
8. Event-Driven Programming
What it is: Flow of the program is determined by events (UI actions, signals, async IO).
How Python supports it:
asyncio, GUI frameworks (Tkinter, PyQt), network servers (Twisted).Example (asyncio):
pythonimport asyncio async def greet(): await asyncio.sleep(1) print("Hello async!") asyncio.run(greet())
9. Concurrent / Parallel Programming
What it is: Multiple threads or processes working together.
How Python supports it:
threading,multiprocessing,asyncio,concurrent.futures.Example:
pythonfrom concurrent.futures import ThreadPoolExecutor def task(n): return n * n with ThreadPoolExecutor() as executor: results = executor.map(task, [1, 2, 3]) print(list(results))
