Lesson · 40 min · Free
Python Classes & OOP
Python Classes & OOP body { font-family: sans-serif; line-height: 1.6; margin: 20px; } h1, h2 { color: #2c3e50; } pre, code { background-color: #ecf0f1; padding: 10px; border-radius: 5px; overflow-x: auto; font-family: '
Python Classes & OOP
Welcome to this lesson on Python Classes and Object-Oriented Programming (OOP). As future professionals in pharmacy and biotechnology, you'll encounter complex systems, whether it's drug discovery pipelines, patient data management, or laboratory automation. OOP provides a powerful paradigm for modeling these real-world entities and their interactions within your code, leading to more organized, reusable, and maintainable software. At its core, OOP revolves around the concept of "objects." An object is a self-contained unit that bundles data (attributes) and the functions that operate on that data (methods). Think of a "Patient" object: it might have attributes like name , age , medical_history , and methods like administer_medication() or update_allergies() . This encapsulation helps manage complexity by keeping related information and behavior together.
Understanding Classes and Objects
In Python, a class serves as a blueprint or a template for creating objects. It defines the structure and behavior that all objects of that class will possess. An object (also known as an instance) is a concrete realization of a class. You can create many objects from a single class, each with its own unique set of attribute values. Let's consider an example relevant to biotechnology: a "Protein" class. A protein has specific attributes like its amino acid sequence, molecular weight, and perhaps a known function. It might also have methods to simulate folding or calculate its isoelectric point. Defining a class allows us to easily create and manage multiple protein instances, each with its distinct characteristics. class Protein: def __init__(self, name, sequence, molecular_weight, function="Unknown"): """ Constructor method for the Protein class. Initializes a new Protein object with specified attributes. """ self.name = name self.sequence = sequence self.molecular_weight = molecular_weight self.function = function def display_info(self): """ Method to display basic information about the protein. """ print(f"Protein Name: {self.name}") print(f"Sequence: {self.sequence[:20]}...") # Show first 20 chars print(f"Molecular Weight: {self.molecular_weight} Da") print(f"Function: {self.function}") def calculate_hydrophobicity(self): """ A placeholder method to simulate a calculation. In a real application, this would involve complex sequence analysis. """ # Simple placeholder logic: counts non-polar amino acids hydrophobic_residues = "AGVILMFWP" count = sum(1 for aa in self.sequence.upper() if aa in hydrophobic_residues) return count / len(self.sequence) if self.sequence else 0 # Creating instances (objects) of the Protein class insulin = Protein("Insulin", "MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKA", 5808, "Regulates glucose metabolism") hemoglobin = Protein("Hemoglobin", "MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSFPTTKTYFPHFDLSHGSAQVKGHGKKVADALTNAVAHVDDMPNALSALSDLLHAHKLRVDPVNFKLLSHCLLVTLAAHLPAEFTPAVHASLDKFLASVSTVLTSKYR", 64500, "Oxygen transport") print("--- Insulin Info ---") insulin.display_info() print(f"Insulin Hydrophobicity: {insulin.calculate_hydrophobicity():.2f}") print("\n--- Hemoglobin Info ---") hemoglobin.display_info() print(f"Hemoglobin Hydrophobicity: {hemoglobin.calculate_hydrophobicity():.2f}") In the code above, Protein is the class. insulin and hemoglobin are objects (instances) of that class. Each object has its own name , sequence , molecular_weight , and function . The __init__ method is a special constructor method that gets called automatically when you create a new object. The self parameter refers to the instance of the class itself, allowing you to access and modify its attributes. OOP promotes several key principles: Encapsulation: Bundling data (attributes) and methods that operate on the data into a single unit (the class). This hides the internal implementation details from the outside world. Inheritance: Allows a new class (subclass) to inherit attributes and methods from an existing class (superclass). This promotes code reuse and establishes a hierarchical relationship (e.g., a "TherapeuticProtein" could inherit from "Protein"). Polymorphism: Allows objects of different classes to be treated as objects of a common type. This means a single interface can be used for different underlying data types, leading to more flexible and extensible code. Abstraction: Hiding complex implementation details and showing only the essential features of an object. Users interact with simplified interfaces without needing to know how the internal mechanisms work. Consider another example, modeling a "Drug" in a pharmacy context. Different drugs might have common properties but also specific behaviors. class Drug: def __init__(self, name, active_ingredient, dosage_mg, administration_route): self.name = name self.active_ingredient = active_ingredient self.dosage_mg = dosage_mg self.administration_route = administration_route def describe(self): return f"{self.name} ({self.active_ingredient}) - {self.dosage_mg}mg via {self.administration_route}" class Tablet(Drug): # Tablet inherits from Drug def __init__(self, name, active_ingredient, dosage_mg, coating_type): super().__init__(name, active_ingredient, dosage_mg, "Oral") # Call parent constructor self.coating_type = coating_type def describe(self): # Overriding the describe method return f"{super().describe()}, with {self.coating_type} coating." class Injectable(Drug): # Injectable also inherits from Drug def __init__(self, name, active_ingredient, dosage_mg, volume_ml, injection_site): super().__init__(name, active_ingredient, dosage_mg, "Injection") self.volume_ml = volume_ml self.injection_site = injection_site def administer(self): return f"Administering {self.name} ({self.dosage_mg}mg in {self.volume_ml}ml) via {self.injection_site} injection." # Creating instances aspirin = Tablet("Aspirin", "Acetylsalicylic Acid", 325, "Enteric") insulin_injection = Injectable("Lantus", "Insulin Glargine", 100, 1.0, "Subcutaneous") print(aspirin.describe()) print(insulin_injection.describe()) # Uses Drug's describe method print(insulin_injection.administer()) In this second example, Tablet and Injectable are subclasses of Drug . They inherit common attributes and methods but can also define their own unique attributes and behaviors, or even override inherited methods (like Tablet 's describe method). This demonstrates inheritance and polymorphism, allowing us to treat various drug forms in a unified yet specialized manner.
Key Takeaways
Classes are blueprints for creating objects, defining attributes (data) and methods (functions). Objects (Instances) are concrete realizations of a class, each with its own state. The __init__ method is the constructor, used to initialize an object's attributes. The self keyword refers to the instance of the class and is used to access instance attributes and methods. OOP principles like Encapsulation, Inheritance, Polymorphism, and Abstraction promote modular, reusable, and maintainable code. OOP is highly valuable for modeling complex real-world systems in fields like pharmacy and biotechnology.
Practice Exercise
Create a Python class called PatientRecord . This class should have attributes for patient_id , name , date_of_birth , and an empty list called medications . Implement a method add_medication(medication_name, dosage) that appends a dictionary {'name': medication_name, 'dosage': dosage} to the medications list. Also, implement a method display_patient_summary() that prints all the patient's information, including their current medications. Create an instance of PatientRecord , add at least two medications, and then display its summary.
Watch the full lesson — free
This topic is part of Python Programming - Basics, a complete AI-narrated video course. Press play once and watch the entire lecture like a movie.
Start the course free →