Skip to content
Dao Xuan Do edited this page Feb 28, 2024 · 1 revision

1. Variables

  • _name: private attribute (chỉ access bên trong class đó
    • có thể truy cập bằng cách sau:
class Fruit:
  def __inti__(self, name, model):
    self.name = name
    self.__model = model
    
fruit: Fruit = Fruit("apple", 100)
print(fruit._Fruit__model)
  • _name: protect variables chỉ được access bên trong class hoặc bên trong class kế thừa
  • có thể sử dụng @name.getter@name.setter để truy cập biến này và
  • ví dụ
class Fruit:
  def __init__(self, name):
    self._name = name
    
  @property
  def name(self):
    print(f'{self._name} is being accessd!')
    return self._name
  
  @name.setter
  def name(self, value: str):
    self._name = value
  
  @name.getter
  def name(self):
    pass

2. __str__, __repr__, __eq__

  • The .__repr__() method returns a detailed description for a programmer who needs to maintain and debug the code. The .__str__() method returns a simpler description with information for the user of the program.
  • .__repr__() provides the official string representation of an object, aimed at the programmer.
  • .__str__() provides the informal string representation of an object, aimed at the user.
  • __eq__ : hàm dùng để so sánh 2 instance object

3. @staticmethod, @classmethod

  • @staticmethod ko cần self , và có thể sử dụng như hàm bình thường cho cả instanceclass đều dùng bình thường
  • @classmethod phải thêm param cls trong hàm
  • example
class Calculator:
  def __init__(self, name: str):
    self.name = name
   
  def description(self):
    print(f'{self.name} is a calculator!')
    
  @staticmethod
  def add_numbers(a: float, b: float):
    print(a+b)
    
  @classmethod
  def create_with_version(cls, name: str, version: int):
    return cls(f'{name}: ({version})')
  

cal : Calculator = Calculator.create_with_version('Bob', 100)
cal.description()

cal.add_numbers(1,2)

###
Bob: (100) is a calculator
-> cal.name = 'Bob: (100)'

4. @abstractmethod

  • Không thể tạo instance từ class chứa @abstractmethod
  • @abstractmethod hữu dụng cho việc đảm bảo bạn không quên implement methods from class, they are useful because they really help us stay consitent
  • example
from abc import ABC, abstractmethod
class Phone(ABC):
  def __init__(self, model: str)
    self.model = model
  
  @abstractmethod
  def call_target(self, person: str)
    ... # ... có nghĩa là hàm này sẽ phải define ở subclass từ parent class Phone
    pass # thì có thể define hoặc ko
  

5. Protocols

  • Cũng được dùng để việc define interface cụ thể methods hoặc attributes cái mà classes cần implement
  • Protocol khác với ABC là nó được thiết kế theo kiểu subtyping (duck typing) , class không cần kế thừa từ một Protocol

duck typing: It means that if two objects have the same methods and attributes, Python will treat them as the same type.

  • example
from typing import Protocol, runtime_checkable
from abc import ABC, abstractmethod

# Protocol 
@runtime_checkable
class PaymentProcessor(Protocol):
    def process_payment(self, amount: float) -> None:
        ...

# ABC
class PaymentGateway(ABC):
    @abstractmethod
    def process_payment(self, amount: float) -> None:
        ...

# Implementing both
class StripeGateway(PaymentGateway):
    def process_payment(self, amount: float) -> None:
        print(f"Processing payment of {amount} via Stripe")

# Usage (note the flexibility with the Protocol)
def handle_checkout(processor: PaymentProcessor, amount: float) -> None:
    processor.process_payment(amount)

my_stripe = StripeGateway()
handle_checkout(my_stripe, 100)  # Works
some_other_processor = ...  # Any other class implementing PaymentProcessor would also work

Protocols offer a more lightweight and flexible approach to defining interfaces, while ABCs provide a stricter template for subclasses within an inheritance hierarchy.

6. __new____init__

  • __new__ is a static method, while __init__ is an instance method
  • __new__ is responsible for creating and returning a new instance, while __init__ is responsible for initializing the attributes of the newly created object.
  • __new__ is called before __init__, __new__ happens first, then __init__.
  • __new__ can return any object, while __init__ must return None
  • example
class Vehicle:
  def __new__(cls, wheels: int):
    if wheels == 2:
      return Motorbike()
    elif wheels == 4:
      return Car()
    else:
      return super().__new__(cls)
  
  def __init__(self, wheels: int):
    self.wheels = wheels

class Motorbike:
  def __init__(self):
    print('Initializaing motorbike')
    
class Car:
  def __init__(self):
    print('Initializaing car')

Clone this wiki locally