Python OOP: Instance Methods & Class Variables (සිංහල Programming Guide)

Python OOP: Instance Methods & Class Variables (සිංහල Programming Guide)

ඉතින් කොහොමද යාලුවනේ! හැමදාම වගේ අදත් මම ඔයාලා වෙනුවෙන් තවත් පට්ටම ලිපියක් අරගෙන ආවා. අද අපි කතා කරන්න යන්නේ Object-Oriented Programming (OOP) වල තවත් වැදගත් සංකල්ප දෙකක් ගැන: Instance Methods සහ Class Variables. මේවා තමයි අපේ code එක clean, organized, සහ maintain කරන්න උදව් කරන ප්‍රධානම දේවල් ටිකක්.

පහුගිය ලිපි වලින් අපි OOP වල මූලිකාංග, Classes සහ Objects ගැන කතා කළා මතකයි නේද? අද අපි ඒ දැනුම තවත් ටිකක් ඉස්සරහට අරගෙන යමු. මේක හරියට, අපේ Car එකට engine එකක් දාලා, ඒක start කරන විදිහයි, ඒ Car එකේ හැමෝටම පොදු වෙන අංකයක් දාන විදිහයි වගේ වැඩක්. සරලව කිව්වොත්, Car එකක් කියන්නේ object එකක් නම්, engine එක start කරන එක instance method එකක්. ඒ වගේම, හැම Car එකකටම පොදු වෙන වාහන ගණන වගේ දෙයක් class variable එකක් වෙන්න පුළුවන්. තේරෙනවනේ නේද?

අපි මේ ගැන විස්තරාත්මකව බලමුකෝ.

Instance Methods - වස්තූන්ගේ ක්‍රියාකාරීත්වය

හරි, මුලින්ම බලමු Instance Methods කියන්නේ මොනවාද කියලා. සරලව කිව්වොත්, Instance Methods කියන්නේ Class එකක් ඇතුලේ define කරපු functions වලට. හැබැයි මේ functions, ඒ Class එකේ Object එකක (instance එකක) තියෙන data (instance variables) එක්ක වැඩ කරන්න පුද්ගලිකවම හදපු ඒවා. හරියට Car එකේ engine එක start කරන්න තියෙන බොත්තම වගේ. ඒ බොත්තම ඔබන්න පුළුවන් ඒ Car එකට විතරයිනේ, වෙන Car එකකට නෙවෙයිනේ.

Instance Method එකක් define කරනකොට, ඒකේ පළවෙනි parameter එක විදිහට හැමවිටම self කියන keyword එක භාවිතා කරනවා. මේ self කියන්නේ අපිට ඒ මොහොතේ වැඩ කරන object එක refer කරන්න පුළුවන් reference එකක්. ඒකෙන් තමයි අපි object එකේම variables (instance variables) access කරන්නේ.

උදාහරණයක් බලමු: Car Class එකට start_engine Method එකක්

අපි අපේ පරණ Car Class එකට start_engine() කියලා method එකක් එකතු කරමු. මේ method එකෙන් වෙන්නේ Car එක start වුණා කියලා message එකක් print කරන එකයි.


class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.is_running = False # Initial state

    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"The {self.year} {self.make} {self.model}'s engine has started!")
        else:
            print(f"The {self.make} {self.model}'s engine is already running.")

    def stop_engine(self):
        if self.is_running:
            self.is_running = False
            print(f"The {self.year} {self.make} {self.model}'s engine has stopped.")
        else:
            print(f"The {self.make} {self.model}'s engine is already off.")

# Objects හදමු
my_car = Car("Toyota", "Corolla", 2020)
friends_car = Car("Honda", "Civic", 2022)

# Methods call කරමු
my_car.start_engine()
my_car.start_engine() # Try starting again
friends_car.start_engine()
my_car.stop_engine()
friends_car.stop_engine()

මේ උදාහරණයේදී, start_engine කියන්නේ Car class එකේ instance method එකක්. මේ method එක ඇතුලේ, self.is_running කියන instance variable එක access කරනවා වගේම, self.make, self.model, self.year වගේ variables පාවිච්චි කරලා, අදාල Car එකේ විස්තරත් print කරනවා. ඒක හරියට "මගේ Car එකේ එන්ජිම ස්ටාර්ට් වුනා!" කියනවා වගේ දෙයක්.

Accessing Instance Variables - වස්තූන්ගේ දත්ත භාවිතය

Instance Methods වල ප්‍රධානම අරමුණක් තමයි ඒ object එකට අදාල දත්ත (instance variables) manipulate කිරීම සහ ඒවට access කිරීම. අපි කලින් දැක්කා වගේ, self කියන parameter එක පාවිච්චි කරලා, අපි self.variable_name කියලා ඒ variables access කරනවා.

get_description Method එකක් හදමු

අපි තවත් method එකක් හදමු, ඒකෙන් Car එකේ make, model, සහ year එක එකතු කරලා ලස්සන description එකක් print කරන්න පුළුවන්. මේකෙන් ඔයාලට තේරෙයි instance methods කොහොමද instance data එක්ක වැඩ කරන්නේ කියලා.


class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.is_running = False

    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"The {self.year} {self.make} {self.model}'s engine has started!")
        else:
            print(f"The {self.make} {self.model}'s engine is already running.")

    def get_description(self):
        return f"This is a {self.year} {self.make} {self.model}."

# Objects හදමු
my_car = Car("Toyota", "Corolla", 2020)
friends_car = Car("Honda", "Civic", 2022)

# Methods call කරමු
print(my_car.get_description())
print(friends_car.get_description())

මේ get_description() method එකෙන් self.year, self.make, සහ self.model කියන instance variables ටික එකතු කරලා, අදාල Car එකට අදාල විස්තරයක් return කරනවා. මේක හරියට Car එකේ ලියකියවිලි බලනවා වගේ වැඩක්. හැම Car එකකටම තමන්ගේම ලියකියවිලි සෙට් එකක් තියෙනවනේ.

Class Variables - පන්තියේ පොදු දත්ත

දැන් අපි කතා කරමු Class Variables ගැන. මේවා Instance Variables වලට වඩා ටිකක් වෙනස්. Class Variable එකක් කියන්නේ Class එකේ හැම Object එකකටම පොදු වෙන variable එකක්. මේක define කරන්නේ Class එක ඇතුලේ, හැබැයි methods වලින් පිට, Class එකේ top level එකේ. හරියට අපේ Car factory එකේ හදපු Car එකතු කරන counter එකක් වගේ. හැම Car එකක්ම හැදුවම මේ counter එක වැඩි වෙනවා.

Class Variables වලට access කරන්න පුළුවන් Class එකේ නම පාවිච්චි කරලා (ClassName.variable_name) හෝ object එකක් පාවිච්චි කරලා (object.variable_name). හැබැයි මතක තියාගන්න ඕන දෙයක් තමයි, Class Variable එකක් object එකක් හරහා modify කළොත්, ඒක අදාල වෙන්නේ ඒ object එකට විතරයි. Class එකට අදාලව modify කරන්න ඕන නම්, Class එකේ නමෙන්ම modify කරන්න ඕනේ.

number_of_cars_created Class Variable එකක් හදමු

අපි අපේ Car Class එකට number_of_cars_created කියලා Class Variable එකක් එකතු කරමු. මේකෙන් අපි බලමු Car Objects කීයක් හදල තියෙනවද කියලා.


class Car:
    number_of_cars_created = 0  # Class Variable

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.is_running = False
        Car.number_of_cars_created += 1 # Increment class variable when a new car is created

    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"The {self.year} {self.make} {self.model}'s engine has started!")
        else:
            print(f"The {self.make} {self.model}'s engine is already running.")

    def get_description(self):
        return f"This is a {self.year} {self.make} {self.model}."

# Objects හදමු
print(f"Cars created before: {Car.number_of_cars_created}") # Accessing class variable via Class name

car1 = Car("Toyota", "Camry", 2021)
car2 = Car("Nissan", "Leaf", 2023)
car3 = Car("Tesla", "Model 3", 2024)

print(f"Cars created after: {Car.number_of_cars_created}") # Accessing class variable via Class name

# You can also access it via an instance, but it's generally preferred to use the class name
print(f"Cars created via car1: {car1.number_of_cars_created}")

මේ උදාහරණයේදී number_of_cars_created කියන්නේ Class Variable එකක්. හැම Car object එකක්ම create කරනකොට, __init__ method එක ඇතුලේ Car.number_of_cars_created එක වැඩි කරනවා. මේක හැම Car object එකකටම පොදු වෙන අගයක්. ඒ කියන්නේ, Car objects 10ක් හැදුවොත්, Car.number_of_cars_created එකේ අගය 10 වෙනවා. මේක "Car factory එකේ නිෂ්පාදනය කරපු මුළු වාහන ගණන" වගේ දෙයක්.

Instance vs. Class Variables - වෙනස තේරුම් ගනිමු

දැන් ඔයාලට Instance Variables සහ Class Variables දෙකම තේරෙනවා ඇති කියලා හිතනවා. ඒත් මේ දෙක අතර තියෙන ප්‍රධාන වෙනස්කම් ටිකක් පැහැදිලිවම බලමු.

Instance Variables:

  • ඒවා define කරන්නේ __init__ method එක ඇතුලේ self.variable_name විදිහට.
  • සෑම object එකකටම තමන්ගේම Instance Variables set එකක් තියෙනවා. ඒ කියන්නේ, Car1 එකට තමන්ගේම make, model එකක් තියෙනවා වගේම, Car2 එකටත් තමන්ගේම වෙන make, model එකක් තියෙනවා.
  • object එකේ state එක save කරන්න භාවිතා කරනවා.
  • Access කරන්නේ object_name.variable_name විදිහට.

Class Variables:

  • ඒවා define කරන්නේ Class එක ඇතුලේ, හැබැයි methods වලින් පිට.
  • Class එකේ හැම object එකකටම මේ variable එක පොදුයි. හැමෝම එකම variable එක share කරනවා.
  • Class එකට අදාල පොදු දත්ත (global data) හෝ constants store කරන්න භාවිතා කරනවා. උදාහරණයක් විදිහට, Car එකක උපරිම වේගය (max_speed) Class variable එකක් විදිහට දාන්න පුළුවන්, මොකද ඒක හැම Car එකකටම පොදුයි.
  • Access කරන්නේ ClassName.variable_name විදිහට (preferred) හෝ object_name.variable_name විදිහට.

පහත code snippet එකෙන් මේ වෙනස තවත් හොඳට තේරුම් ගන්න පුළුවන් වෙයි.


class Product:
    tax_rate = 0.15 # Class Variable (15% tax for all products)

    def __init__(self, name, price):
        self.name = name     # Instance Variable
        self.price = price   # Instance Variable

    def get_price_with_tax(self):
        return self.price * (1 + Product.tax_rate) # Accessing class variable

# Objects හදමු
laptop = Product("Laptop", 1200)
phone = Product("Smartphone", 800)

# Instance Variables
print(f"Laptop Name: {laptop.name}, Price: {laptop.price}")
print(f"Phone Name: {phone.name}, Price: {phone.price}")

# Class Variable
print(f"Current Tax Rate: {Product.tax_rate}") # Accessing via Class Name
print(f"Laptop's Tax Rate: {laptop.tax_rate}") # Accessing via instance (reads from class)

# Change Class Variable
Product.tax_rate = 0.18 # Tax rate changed for ALL products
print(f"New Tax Rate: {Product.tax_rate}")

# See impact on instances
print(f"Laptop's new tax rate (via instance): {laptop.tax_rate}")
print(f"Phone's new tax rate (via instance): {phone.tax_rate}")

# Calculate price with new tax
print(f"Laptop Price with new Tax: {laptop.get_price_with_tax():.2f}")
print(f"Phone Price with new Tax: {phone.get_price_with_tax():.2f}")

# What happens if you try to modify a class variable using an instance?
# This creates a NEW instance variable with the same name, shadowing the class variable for THIS instance.
my_specific_product = Product("Custom Gadget", 500)
my_specific_product.tax_rate = 0.10 # This creates an instance variable `tax_rate` for my_specific_product

print(f"My specific product's tax rate (instance variable): {my_specific_product.tax_rate}")
print(f"Global tax rate (class variable): {Product.tax_rate}") # Remains 0.18

# If you then access tax_rate via my_specific_product, it will return its own instance variable.
# If you access via another instance (e.g., laptop), it will still refer to the class variable.
print(f"Laptop's tax rate (still refers to class): {laptop.tax_rate}")

මේ උදාහරණයේදී tax_rate කියන්නේ Class Variable එකක්. මේක Class එකේ නම පාවිච්චි කරලා වෙනස් කළොත්, ඒක හැම Product object එකකටම අදාල වෙනවා. හැබැයි, my_specific_product.tax_rate = 0.10 කියලා දැම්මම, ඒ my_specific_product කියන object එකට විතරක් අදාල වෙන අලුත් instance variable එකක් හැදෙනවා. මේක "Shadowing" කියලා හඳුන්වනවා. මේ වගේ දේවල් වෙන්න පුළුවන් නිසා Class Variables modify කරනකොට Class name එකෙන්ම modify කරන්න මතක තියාගන්න.

Best Practices - හොඳ පුරුදු

දැන් අපි මේ concepts ටික පාවිච්චි කරනකොට මතක තියාගන්න ඕන හොඳ පුරුදු ටිකක් බලමු.

  1. Methods වලින් Object State එක Manage කරන්න:
    • object එකක data (instance variables) කෙලින්ම වෙනස් කරනවාට වඩා, ඒ වෙනුවෙන් methods හදන්න. උදාහරණයක් විදිහට, my_car.is_running = True කියලා කෙලින්ම දානවාට වඩා my_car.start_engine() වගේ method එකක් භාවිතා කරන එක හොඳයි. මේක Encapsulation කියලා හඳුන්වනවා. මේකෙන් අපේ code එක maintain කරන්න සහ debug කරන්න පහසු වෙනවා.
    • ඒ වගේම, data retrieve කරන්නත් methods භාවිතා කරන්න. my_car.get_description() වගේ.
  2. නිරවද්‍ය Class Variable භාවිතය:
    • Class variables භාවිතා කරන්න ඕනේ හැම object එකකටම පොදු වෙන දත්ත (shared attributes) හෝ constants (නොවෙනස්වන අගයන්) ගබඩා කරන්න විතරයි.
    • Class variable එකක් modify කරනකොට, හැමවිටම Class name එක පාවිච්චි කරන්න (ClassName.variable = new_value). object instance එකක් හරහා modify කළොත්, ඒකෙන් ඒ instance එකට අලුත් instance variable එකක් හැදෙනවා මිසක්, Class variable එක වෙනස් වෙන්නේ නැහැ.
  3. Readability සහ Naming Conventions:
    • ඔයාගේ code එක කියවන්න ලේසි වෙන්න, variables සහ methods වලට තේරුමක් තියෙන නම් දෙන්න. Python වලදී, snake_case (අකුරු සිම්පල්, වචන වෙන් කරන්න underscore) තමයි සාමාන්‍යයෙන් භාවිතා කරන්නේ.
    • Class names වලට CamelCase (පළවෙනි අකුරු කැපිටල්) භාවිතා කරන්න.

මේ හොඳ පුරුදු අනුගමනය කරන එකෙන් ඔයාලට quality code ලියන්න පුළුවන් වෙනවා. හරියට Car එකක් හොඳට design කරලා, හදපු ගමන්ම පාරේ යන්න පුළුවන් විදිහට හදනවා වගේ වැඩක්.

නිගමනය

ඉතින් යාලුවනේ, අද අපි Object-Oriented Programming වල හරිම වැදගත් concepts දෙකක් ගැන කතා කළා: Instance Methods සහ Class Variables. මේවා තමයි අපේ program වලට ජීවය දෙන, ඒවා තවත් බලවත් කරන tools ටිකක්.

  • Instance Methods: වස්තූන්ගේ පුද්ගලික දත්ත (instance variables) සමග වැඩ කරන්න සහ වස්තුවේ ක්‍රියාකාරීත්වය (behavior) define කරන්න භාවිතා වෙනවා. හැම object එකකටම තමන්ගේම methods තියෙනවා.
  • Class Variables: Class එකේ හැම object එකකටම පොදු වෙන දත්ත ගබඩා කරන්න භාවිතා වෙනවා. මේවා class එකට අදාලයි, object එකට නෙවෙයි.

මේ සංකල්ප දෙක හරියට තේරුම් ගැනීම, ඔයාලගේ OOP ගමනට ලොකු ශක්තියක් වෙයි. code එක clean, reusable, සහ extendable විදිහට ලියන්න මේවා උදව් කරනවා. හරියට අපේ Car එකේ Engine එකයි, Registration number එකයි වගේ. දෙකම Car එකේ කොටස්, හැබැයි දෙකේම ප්‍රයෝජන වෙනස්.

මේ ගැන ඔයාලට මොනවා හරි ප්‍රශ්න තියෙනවා නම්, නැත්නම් ඔයාලා මේ concepts පාවිච්චි කරපු interesting project එකක් ගැන කියන්න තියෙනවා නම්, පහලින් comment කරන්න. පුළුවන් නම්, මේ Car class එකට තවත් methods (e.g., accelerate(), brake()) සහ class variables (e.g., manufacturer_country) එකතු කරලා පොඩි program එකක් ලියලා බලන්න. Practice කරන තරමට ඔයාලා perfect වෙනවා!

ඊළඟ ලිපියෙන් හම්බවෙමු! පරිස්සමෙන් ඉන්න!