oop in python

magic functions

class tt:
    text:str
    def __init__(self,value):
        self.text = value
    def __str__(self):#print(obj)
        return self.text
    def __repr__(self):#print(obj) return obj.text
        return self.text
    def __add__(self, other):#obj+other return obj.text+other.text
        return self.text+other.text
    def __len__(self):#len(obj)  return len(obj.text)
        return len(self.text)
    def __getattr__(self, item):#obj.item return item
        return item
    def __getitem__(self, item):#obj[item] return item
        return item
    def __call__(self, *args, **kwargs):#obj() return obj.text
        return self.text
    def __eq__(self, other):#obj==other return obj.text==other.text
        return self.text==other.text
    def __ne__(self, other):#obj!=other return obj.text!=other.text
        return self.text!=other.text
    def __iter__(self):#for i in obj: return obj.text
        return iter(self.text)
class A:
    def __getitem__(self, item):
        if(isinstance(item, slice)):
            print(item.start)
            print(item.stop)
            print(item.step)

a = A()
a[1:3:4]

generic class

from typing import TypeVar, Generic

T = TypeVar('T',int , float,complex,decimal.Decimal)
class Stack(Generic[T]):
    def __init__(self) -> None:
        # Create an empty list with items of type T
        self.items: list[T] = []

    def push(self, item: T) -> None:
        self.items.append(item)

    def pop(self) -> T:
        return self.items.pop()

    def empty(self) -> bool:
        return not self.items

predefined static properties

  • __dict__ − Dictionary containing the class’s namespace.
  • __doc__ − Class documentation string or none, if undefined.
  • __name__ − Class name.
  • __module__ − Module name in which the class is defined. This attribute is “__main__” in interactive mode.
  • __bases__ − A possibly empty tuple containing the base classes, in the order of their occurrence in the base class list.
class Employee:
   def __init__(self, name="Bhavana", age=24):
      self.name = name
      self.age = age
   def displayEmployee(self):
      print ("Name : ", self.name, ", age: ", self.age)

print ("Employee.__doc__:", Employee.__doc__)
print ("Employee.__name__:", Employee.__name__)
print ("Employee.__module__:", Employee.__module__)
print ("Employee.__bases__:", Employee.__bases__)
print ("Employee.__dict__:", Employee.__dict__ )

abstraction

from abc import ABC, abstractmethod
class demo(ABC):
   @abstractmethod
   def method1(self):
      print ("abstract method")
      return
   def method2(self):
      print ("concrete method")

access modifier

class Employee:
   def __init__(self, name, age, salary):
      self.name = name # public variable
      self.__age = age # private variable
      self._salary = salary # protected variable
   def displayEmployee(self):
      print ("Name : ", self.name, ", age: ", self.__age, ", salary: ", self._salary)

e1=Employee("Bhavana", 24, 10000)

print (e1.name)
print (e1._salary)
print (e1.__age)

enum

from enum import Enum

class subjects(Enum):
   ENGLISH = "E"
   MATHS = "M"
   GEOGRAPHY = "G"
   SANSKRIT = "S"
   
obj = subjects.SANSKRIT
print (type(obj), obj.name, obj.value)#<enum 'subjects'> SANSKRIT S

from enum import Enum, unique

@unique
class subjects(Enum):
   ENGLISH = 1
   MATHS = 2
   GEOGRAPHY = 3
   SANSKRIT = 2#error value duplicated

reflections

class test:
   pass
   
obj = test()
print (type(obj))#<class '__main__.test'>

print (isinstance(10, int))#true
print (isinstance(2.56, float))#true
print (isinstance(2+3j, complex))#true
print (isinstance("Hello World", str))#true

def test():
   pass
   
print (callable("Hello"))
print (callable(abs))#true
print (callable(list.clear([1,2])))
print (callable(test))#true

class test:
   def __init__(self):
      self.name = "Manav"
      
obj = test()
print (getattr(obj, "name"))

class test:
   def __init__(self):
      self.name = "Manav"
      
obj = test()
setattr(obj, "age", 20)
setattr(obj, "name", "Madhav")
print (obj.name, obj.age)

class test:
   def __init__(self):
      self.name = "Manav"
      
obj = test()
print (hasattr(obj, "age"))
print (hasattr(obj, "name"))

dir(object) # get list of attributes belong to the object

static methods

class A:
    value: int=14 #static variable you can access it by A.value
    @staticmethod
    def bar():#static method
        print("bar")

other way to call method

class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def mm(self):
        return self.x, self.y
fun=A.mm(A(1,2))
print(fun)  # (1, 2)

setter and getter

# employee.py

from datetime import date

class Employee:
    def __init__(self, name, birth_date, start_date):
        self.name = name
        self.birth_date = birth_date
        self.start_date = start_date

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value.upper()

    @property
    def birth_date(self):
        return self._birth_date

    @birth_date.setter
    def birth_date(self, value):
        self._birth_date = date.fromisoformat(value)

    @property
    def start_date(self):
        return self._start_date

    @start_date.setter
    def start_date(self, value):
        self._start_date = date.fromisoformat(value)