Created
June 12, 2023 00:36
-
-
Save Drblessing/e096022ce0b2c77e6e6d5219b65b278f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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