Python Classroom Series – 04/Sept/2021

Class and object attributes

  • In python, we can assign attributes to the class, which will be shared by all the instances
class Student:
    count = 0 # class attribute

    def __init__(self, name, course) -> None:
        self.name = name # object/instance attributes
        self.course = course # object/instance attributes
        Student.count += 1

    def __str__(self) -> str:
        return f"name: {self.name}, course: {self.course}, count: {Student.count}"

if __name__ == "__main__":
    s1 = Student('khaja', 'python')
    print(Student.count)
    print(s1.count)
    print(s1)
    s2 = Student('Ramana', "Testing")
    print(Student.count)
    print(s2)
    print(s2.count)
    print(s1.count)

  • Instance attriutes are created per instance and will have different values (memory locations) per object where as class attributes are shared across instances.

Method Types

  • Python has methods which are part of the class itself, some are part of objects and some are none of the above
    • If there’s no preceding decorator, its an instance method and its first argument should be self to refer invidual object itself
    • If there’s a preceding @classmethod decorator, its a class method and its first argument should be cls referring to class
    • If there’s a preceding @staticmethod decorator, its a static method
  • Instance Methods: whenever you see and initial self argument in a method within a class definition its a instance method. Thes methods are used after creating an object from the class
  • Class Method: In contrast, a class method effect the class as whole.
  • Static Method: A third type of method in class affects neither the class nor its objects. Its just in there for convenience instad of floating around on is own.
class Car:
    count = 0

    def __init__(self) -> None:
        Car.count += 1
    
    def info(self):
        print("Im a car")

    @classmethod
    def more_info(cls):
        print(f"Car has {cls.count} instances")

    @staticmethod
    def format_message():
        print("formatting message")

Car.more_info()
c1 = Car()
c1.info()
Car.format_message()
  • One more example
class Tea:
    def __init__(self, ingredients) -> None:
        self.ingredients = ingredients

    def __str__(self) -> str:
        return (f"Tea({self.ingredients})")

    def prepare(self):
        print("combing ingredients")
        print("tea is ready")

    @classmethod
    def lemon_tea(cls):
        return cls(['water', 'teapowder', 'lemon'])

    @classmethod
    def green_tea(cls):
        return cls(['water', 'greentea', 'lemon', 'honey'])


lt = Tea.lemon_tea()
gt = Tea.green_tea()
print(lt)
print(gt)
lt.prepare()
gt.prepare()
  • One more example
class Employee:
    count = 0

    def __init__(self, first_name: str, last_name: str, salary: float, department: str) -> None:
        self.first_name = first_name
        self.last_name = last_name
        self.salary = salary
        self.department = department
        self.increment_employees()

    def give_hike(self, amount):
        self.salary += amount

    @classmethod
    def increment_employees(cls):
        cls.count += 1

    @staticmethod
    def get_employee_legal_obligations_text():
        legal_obligations = """
        1. An employee must complete 8 hours per working day
        2. An employee's contract can be cancelled anytime
        """

if __name__ == '__main__':
    e1 = Employee('khaja', 'ibrahim', 10000, 'R&D')
    e2 = Employee('ram', 'l', 5000, 'management')
    e1.give_hike(10000)
    e2.give_hike(5000)
    print(e1.salary)
    print(e2.salary)
    print(Employee.get_employee_legal_obligations_text())

Duck typing

  • Python has a loose implementation of polymorphism, it applies to different objects, based on method names and arguments, regardless of their class
  • Look at the below example
class Quote():
    def __init__(self, person, words) -> None:
        self.person = person
        self.words = words

    def who(self):
        return self.person

    def says(self):
        return self.words + "."

class QuestionQuote(Quote):
    def says(self):
        return self.words + "?"

class ExclamationQuote(Quote):
    def says(self):
        return self.words + "!"

class Duck:
    def who(self):
        return "Duck"

    def says(self):
        return "Quack Quack"


def who_says(quote):
    print(quote.who(), 'says', quote.says())

if __name__ == '__main__':
    nm_quote = Quote('Nelson Mandela', 'The greatest glory in living lies not in never falling, but in rising every time we fall')
    who_says(nm_quote)

    wd_quote = QuestionQuote('Walt Disney', 'The way to get started is to quit talking and begin doing')
    who_says(wd_quote)

    jl_quote = ExclamationQuote('John Lennon', 'Life is what happens when youre busy making other plans')
    who_says(jl_quote)

    duck = Duck()
    who_says(duck)

  • This behavior is called as duck typing if it walks like a duck and quacks like a duck its a duck

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About learningthoughtsadmin