Lesson · 40 min · Free
Python Inheritance & OOP
Python Inheritance & OOP body { font-family: sans-serif; line-height: 1.6; color: #333; } h1, h2 { color: #0056b3; } pre { background-color: #f4f4f4; padding: 15px; border: 1px solid #ddd; overflow-x: auto; margin-bottom
Python Inheritance & OOP
Welcome to this lesson on Python Inheritance and Object-Oriented Programming (OOP) within the context of pharmaceutical research. OOP is a powerful programming paradigm that allows us to structure our code in a way that models real-world entities and their relationships. In pharmaceutical research, this can be incredibly useful for representing biological molecules, experimental data, or even complex analytical workflows. At its core, OOP revolves around the concept of "objects," which are instances of "classes." A class is essentially a blueprint for creating objects, defining their properties (attributes) and behaviors (methods). Inheritance is a fundamental principle of OOP that allows a new class (a "child" or "subclass") to inherit attributes and methods from an existing class (a "parent" or "superclass"). This promotes code reusability, reduces redundancy, and makes our programs more organized and maintainable, which are all crucial in complex scientific computing.
Understanding Inheritance in Pharmaceutical Data Modeling
Consider a scenario where we are developing a system to manage information about various drug compounds. We might have a general Compound class with attributes like name , molecular_weight , and chemical_formula . However, some compounds are specifically "Small Molecule Drugs," and others are "Biologics." These specialized types of compounds will have additional, unique attributes and behaviors. Instead of creating entirely new classes from scratch, inheritance allows us to build upon the existing Compound class. By inheriting from Compound , our SmallMoleculeDrug and Biologic classes automatically gain all the properties and methods of a general compound, and we can then add their specific characteristics. For example, a SmallMoleculeDrug might have an attribute for oral_bioavailability , while a Biologic might have production_cell_line . This hierarchical structure accurately reflects the relationships between different types of pharmaceutical entities. Let's look at a basic example of how inheritance works in Python: class Compound: def __init__(self, name, molecular_weight, chemical_formula): self.name = name self.molecular_weight = molecular_weight self.chemical_formula = chemical_formula def get_info(self): return f"Compound: {self.name}, MW: {self.molecular_weight} g/mol, Formula: {self.chemical_formula}" class SmallMoleculeDrug(Compound): def __init__(self, name, molecular_weight, chemical_formula, oral_bioavailability): super().__init__(name, molecular_weight, chemical_formula) # Call parent constructor self.oral_bioavailability = oral_bioavailability def get_drug_info(self): return f"{self.get_info()}, Bioavailability: {self.oral_bioavailability}%" # Create instances aspirin = SmallMoleculeDrug("Aspirin", 180.16, "C9H8O4", 90) print(aspirin.get_info()) print(aspirin.get_drug_info()) # Example of another subclass class Biologic(Compound): def __init__(self, name, molecular_weight, chemical_formula, production_cell_line): super().__init__(name, molecular_weight, chemical_formula) self.production_cell_line = production_cell_line def get_biologic_details(self): return f"{self.get_info()}, Produced in: {self.production_cell_line}" insulin = Biologic("Insulin", 5808, "C257H383N65O77S6", "E. coli") print(insulin.get_biologic_details()) In this example, SmallMoleculeDrug and Biologic inherit from Compound . Notice the use of super().__init__() . This is crucial for calling the constructor of the parent class, ensuring that the parent's attributes are properly initialized before the subclass adds its own. This prevents us from having to redefine name , molecular_weight , and chemical_formula in each subclass. Inheritance also supports method overriding. This means a subclass can provide a specific implementation for a method that is already defined in its parent class. This is useful when a behavior needs to be slightly different for a specialized type of object. Consider enhancing our Compound class with a method to calculate the logP (octanol-water partition coefficient), which is relevant for drug discovery. While a general calculation might exist, specific methods or experimental data might be available for small molecules versus biologics. class Compound: def __init__(self, name, molecular_weight, chemical_formula): self.name = name self.molecular_weight = molecular_weight self.chemical_formula = chemical_formula def calculate_logP(self): # A very basic, generic placeholder calculation # In a real scenario, this would be a more complex model or lookup return len(self.chemical_formula) * 0.1 # Placeholder class SmallMoleculeDrug(Compound): def __init__(self, name, molecular_weight, chemical_formula, oral_bioavailability): super().__init__(name, molecular_weight, chemical_formula) self.oral_bioavailability = oral_bioavailability def calculate_logP(self): # Override for small molecules, perhaps using a fragment-based method # This is still a placeholder, but demonstrates overriding print(f"Calculating LogP for {self.name} using small molecule model...") return (len(self.chemical_formula) * 0.15) + (self.molecular_weight / 1000) class Biologic(Compound): def __init__(self, name, molecular_weight, chemical_formula, production_cell_line): super().__init__(name, molecular_weight, chemical_formula) self.production_cell_line = production_cell_line def calculate_logP(self): # LogP for biologics is often more complex or not directly comparable print(f"LogP for {self.name} (Biologic) is often not directly applicable or requires specialized methods.") return None # Or a different calculation if appropriate # Test the overridden methods generic_compound = Compound("Water", 18.015, "H2O") print(f"{generic_compound.name} LogP: {generic_compound.calculate_logP()}") aspirin = SmallMoleculeDrug("Aspirin", 180.16, "C9H8O4", 90) print(f"{aspirin.name} LogP: {aspirin.calculate_logP()}") insulin = Biologic("Insulin", 5808, "C257H383N65O77S6", "E. coli") print(f"{insulin.name} LogP: {insulin.calculate_logP()}") This demonstrates how calculate_logP behaves differently depending on the specific class of the object, even though they all originated from the same parent Compound class. This is a core aspect of polymorphism, another key OOP concept closely related to inheritance, where objects of different classes can be treated through a common interface.
Key Takeaways
Classes and Objects: Classes are blueprints, objects are instances. Inheritance: Allows a new class (subclass) to acquire attributes and methods from an existing class (superclass). Code Reusability: Reduces duplicate code by sharing common functionalities. super().__init__() : Essential for calling the parent class's constructor to initialize inherited attributes. Method Overriding: Subclasses can provide their own implementation of a method defined in the parent class. Polymorphism: Objects of different classes can be treated uniformly through a common interface, often enabled by inheritance. Modeling Real-World Entities: OOP helps structure complex pharmaceutical data and processes logically.
Practice Exercise: Extending an Experiment Class
Imagine you have a base class called Experiment with attributes like experiment_id , start_date , and a method run_experiment() that prints a generic message. Create two subclasses: CellCultureExperiment and AnimalStudy . Each subclass should: Inherit from the Experiment class. Add at least two unique attributes specific to that type of experiment (e.g., cell_line and passage_number for cell culture, or animal_species and number_of_animals for animal study). Override the run_experiment() method to print a message specific to that type of experiment, incorporating its unique attributes. Create an instance of each subclass and call their respective run_experiment() methods.
Watch the full lesson — free
This topic is part of Python for Pharmaceutical Research, a complete AI-narrated video course. Press play once and watch the entire lecture like a movie.
Start the course free →