Skip to content

Instantly share code, notes, and snippets.

@Drblessing
Created June 12, 2023 00:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Drblessing/e096022ce0b2c77e6e6d5219b65b278f to your computer and use it in GitHub Desktop.
Save Drblessing/e096022ce0b2c77e6e6d5219b65b278f to your computer and use it in GitHub Desktop.
# Python OOP Examples
from abc import ABC, abstractmethod
from datetime import datetime
# Abstract Base Class
# Defines abstract methods that must be implemented
class Building(ABC):
# Properties are managed attributes
@property
@abstractmethod
def num_rooms(self) -> int:
pass
@property
@abstractmethod
def sq_ft(self) -> int:
pass
# Descriptor Class
# Properties, static methods, and class methods
# are all descriptors
class HouseTime:
def __get__(self, obj, objtype=None):
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
class House(Building):
"""
This class represents a house.
"""
# Class attribute
# All instances and Class itself have reference
# to the same id and value
house_roofs = ["flat", "slanted", "pointed"]
# Instance attribute, a descriptor
house_time = HouseTime()
def __init__(self, num_rooms: int = 3, sq_ft: int = 2000):
# Instance attributes
self._num_rooms: int = num_rooms
self._sq_ft: int = sq_ft
# Turns an instance method into a property
# Properties are managed instance attributes
@property
def num_rooms(self) -> int:
return self._num_rooms
# Setter for num_rooms property
# If a property has a setter, it is called a managed attribute
# If a property has no setter, it is called a read-only attribute
@num_rooms.setter
def num_rooms(self, value) -> None:
print("Setting num rooms")
self._num_rooms = value
# Read-only property
@property
def sq_ft(self):
return self._sq_ft
# Read-only property
@property
def value(self) -> int:
return self._num_rooms * self._sq_ft
# Static methods, no access to instance or class
# Mainly used for namespacing
@staticmethod
def house_colors() -> list:
return ["red", "blue", "green"]
# Class methods, access to class but not instance
# Mainly used for namespacing
@classmethod
def house_colors2(cls) -> list:
return ["red", "blue", "green"]
# Instance methods, access to instance but not class
def print_house(self) -> None:
print(f"House has {self._num_rooms} rooms and is {self._sq_ft} sq ft")
h = House(3, 2000)
print("Num rooms instance property:", h.num_rooms)
h.num_rooms = 4
print("Sq ft read-only property:", h.sq_ft)
print("Home Value read-only property. Never set, depends on other attributes:", h.value)
print("House colors static method:", House.house_colors())
print("House colors2 class method:", House.house_colors2())
print("Class method has same id for all instances and class itself.")
print(
"id(a.house_colors2) == id(House.house_colors2) :",
id(h.house_colors2) == id(House.house_colors2),
)
print(
"a.house_colors2.__func__ is House.house_colors2.__func__ is House().house_colors2.__func__",
h.house_colors2.__func__
is House.house_colors2.__func__
is House().house_colors2.__func__,
)
print("Instance method: h.print_house()")
h.print_house()
# We've covered the basics of OOP in Python
# Instance attributes: self._attribute
# Values that are unique to each instance
# They can't run computations, just values
# because when they are defined, the data function is called.
# Class attributes: attribute
# Defined outside of __init__,
# they are shared by all instances and the class itself.
# They can also not run computations, just values
# for their simple use case. They are defined when the class is defined.
# Class atributes are typically used for constants that
# don't change from instance to instance.
# Properties: @property
# They are managed instance attributes, they can run computations.
# Can have getter and setter methods.
# Static methods: @staticmethod
# They are namespaced methods, they can't access instance or class.
# Class methods: @classmethod
# They are namespaced methods, they can access class but not instance.
# Instance methods: def method(self)
# They can access instance but not class.
# They are the most common type of method.
# They are defined when the class is defined.
# Descriptors: class Time
# They are used to implement properties, static methods, and class methods.
# Properties are more commonly used than static and class methods, and descriptors
# The one advantage of descriptors is they can be reused in multiple classes,
# unlike properties, static methods, and class methods.
# Protected attributes: self._attribute
# They are not really protected, but they are a convention
# to tell other developers not to use them.
# Private attributes: self.__attribute
# They are not really private, but they are a convention
# to tell other developers not to use them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment