2.4 Palatable Python_Basic Syntax#4_Class

mseokq23·2024년 12월 31일

Palatable Python

목록 보기
7/11
post-thumbnail

2.4 Class

2.4.1 Classes and Object-Oriented Programming (OOP)

2.4.1.1 What is OOP?

Object (Instance):
A specific entity that is created following a blueprint (class).
It holds data (variables) and functions (methods) to manipulate that data.

Class: The blueprint or template used to create objects. It defines the structure and behaviors that its instances will have.
Object-Oriented Programming (OOP): A programming paradigm that organizes code by bundling data and behavior into objects.
Benefits of OOP include reusability, maintainability, and extensibility of code.
For example, you can have a Car class that serves as a blueprint for creating different car objects, each with its own unique properties.

2.4.2 Defining a Class in Python

In Python, you define a class using the class keyword:

class ClassName:
    # class variables
    # methods (functions) go here

Naming Convention: By convention, class names in Python typically use CamelCase (e.g., MyClass, StudentInfo, Car).

2.4.2.1 Class Variables vs. Instance Variables

  • Class Variable: A variable shared by all instances of a class.
  • Instance Variable: A variable that is unique to each instance. Typically defined inside the __init__ constructor method.
class Animal:
    species = "Animal"  # Class variable

    def __init__(self, name, age):
        # Instance variables
        self.name = name
        self.age = age

2.4.3 Constructor and Destructor

2.4.3.1 Constructor (__init__)

This special method is automatically called when a class is instantiated (i.e., when you create an object). It is commonly used to initialize instance variables.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# Usage
p = Person("Alice", 25)  # __init__ is called automatically
print(p.name)  # Alice
print(p.age)   # 25

2.4.3.2 Destructor (__del__)

Called automatically when an instance is about to be destroyed. Python uses garbage collection, so you rarely need to manually free memory. Destructors are typically used for releasing external resources if necessary.

class Person:
    def __init__(self, name):
        self.name = name

    def __del__(self):
        print(f"Instance of {self.name} is being destroyed.")

2.4.4 Methods in Python

  • A method is simply a function defined inside a class.
  1. Instance Method: Takes self as the first argument and can access instance variables.
  2. Class Method: Takes cls as the first argument and can access class variables. Decorated with @classmethod.
  3. Static Method: Does not take self or cls as the first argument. Works like a regular function but is defined inside the class. Decorated with @staticmethod.
class MyClass:
    # Class variable
    class_var = "This is a class variable"

    def __init__(self, value):
        # Instance variable
        self.value = value

    def instance_method(self):
        """
        An instance method can access both
        instance variables and class variables.
        """
        print(f"Instance method: self.value = {self.value}")
        print(f"Instance method: MyClass.class_var = {MyClass.class_var}")

    @classmethod
    def class_method(cls):
        """
        A class method can access the class
        (and thus class variables), but not specific instances.
        """
        print(f"Class method: cls.class_var = {cls.class_var}")

    @staticmethod
    def static_method():
        """
        A static method does not take self or cls.
        It's essentially a regular function inside the class namespace.
        """
        print("Static method called")

2.4.5 Access Control

  • Python does not enforce strict access modifiers (like public, private, protected in languages such as C++/Java). Instead, it relies on naming conventions to signal a developer’s intention:
  1. Single underscore (_var or _method): Indicates the attribute or method is for internal use only; other developers are discouraged from using it directly.

  2. Double underscore (__var or __method): Indicates even stronger intent for internal use only. Python performs name mangling in this case, though it’s still accessible if you know how (e.g., _ClassName__var).

class MyClass:
    def __init__(self):
        self.public_var = "public variable"
        self._internal_var = "internal variable (not recommended to use externally)"
        self.__secret_var = "private variable"

    def public_method(self):
        print("Public method")

    def _internal_method(self):
        print("Internal method")

    def __secret_method(self):
        print("Secret method")

2.4.6 Inheritance

2.4.6.1 Concept of Inheritance

Allows a new class (child or subclass) to inherit attributes and methods from an existing class (parent or superclass).

Enhances code reusability and helps maintain a clear hierarchy.

2.4.6.2 Inheritance Syntax

class ParentClass:
    def parent_method(self):
        print("Parent class method")

class ChildClass(ParentClass):
    def child_method(self):
        print("Child class method")

2.4.6.3 Method Overriding

A subclass can override (redefine) a method from its superclass.

class Animal:
    def speak(self):
        print("Animals can make sounds.")

class Dog(Animal):
    def speak(self):
        print("Woof!")  # Overrides the parent speak method

dog = Dog()
dog.speak()  # Woof!

2.4.6.4 super() Function

Used to call the parent class’s methods from the child class:

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # Call the parent constructor
        self.breed = breed

2.4.7 Polymorphism

Polymorphism means different classes can define the same method in different ways:

class Cat:
    def speak(self):
        print("Meow")

class Dog:
    def speak(self):
        print("Woof")

def make_sound(animal):
    animal.speak()

cat = Cat()
dog = Dog()

make_sound(cat)  # Meow
make_sound(dog)  # Woof

2.4.8 Example: Simple Bank Account Class

class BankAccount:
    # Class variable (e.g., an interest rate that applies to all accounts)
    interest_rate = 0.02

    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        """Deposit method"""
        self.balance += amount
        print(f"Deposited {amount}. New balance: {self.balance}")

    def withdraw(self, amount):
        """Withdraw method"""
        if self.balance >= amount:
            self.balance -= amount
            print(f"Withdrew {amount}. New balance: {self.balance}")
        else:
            print("Insufficient balance")

    @classmethod
    def set_interest_rate(cls, rate):
        """Class method to modify the interest rate"""
        cls.interest_rate = rate

    @staticmethod
    def bank_info():
        """Static method: general information"""
        print("Welcome to PyBank!")

# Usage
BankAccount.bank_info()         # Static method
account1 = BankAccount("Alice", 1000)
account1.deposit(500)          # Deposits 500
account1.withdraw(200)         # Withdraws 200

print(BankAccount.interest_rate)  # 0.02

BankAccount.set_interest_rate(0.03)
print(BankAccount.interest_rate)  # 0.03

0개의 댓글