Functions eliminate code duplication by packaging reusable logic into named blocks. Declare them using the def keyword followed by an identifier and parentheses.
def greet():
print("Function executed")
greet()
Parameters make functiosn flexible by accepting external data. Define required and optional parameters within the parentheses:
def calculate(base, multiplier=1):
return base * multiplier
# Positional arguments
calculate(10, 3)
# Keyword arguments
calculate(multiplier=5, base=2)
Handle variable argument counts using special syntax:
# Collects positional arguments into a tuple
def process_items(*items):
for item in items:
print(item)
# Collects keyword arguments into a dictionary
def configure(**settings):
for key, value in settings.items():
print(f"{key}: {value}")
The return statement terminates execution and sends values back to the caller. Functions without explicit returns yield None.
Object-oriented programming structures code around objects representing real-world entities. A class serves as a blueprint defining characteristics and bheaviors, while an object constitutes a specific manifestation of that blueprint.
class Vehicle:
def __init__(self, manufacturer, year):
self.manufacturer = manufacturer
self.year = year
def start(self):
print(f"{self.manufacturer} engine started")
# Creating an instance
car = Vehicle("Toyota", 2023)
car.start()
The self parameter references the instance automatically, binding attributes to specific objects. Instance variables attached to self persist throughout the object's lifetime.
Encapsulation restricts external access to internal state. Prefix attributes with double underscores to invoke name mangling, making them effectively private:
class BankAccount:
def __init__(self):
self.__balance = 0
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self):
return self.__balance
Inheritance enables hierarchical code reuse through parent-child relationships:
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
def work(self):
print("Performing general tasks")
class Developer(Employee):
def __init__(self, name, salary, language):
super().__init__(name, salary)
self.language = language
def work(self):
print(f"{self.name} coding in {self.language}")
Polymorphism allows subclasses to provide specific implementations of methods defined in parent classes:
class Shape:
def area(self):
raise NotImplementedError
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
shapes = [Rectangle(5, 3), Circle(4)]
for shape in shapes:
print(shape.area())