පයිතන් OOP: Constructors සහ Instance Variables ගැන ඉගෙනගමු

පයිතන් OOP: Constructors සහ Instance Variables ගැන ඉගෙනගමු

ආයුබෝවන් කට්ටිය! කොහොමද ඉතින් ඔක්කොටම? මේ දවස්වල හොඳටම වැඩද? අද අපි කතා කරන්න යන්නේ Python Object-Oriented Programming (OOP) වල ඉතාම වැදගත් කොටසක් ගැන. මේක හරියට ගෙයක් හදනකොට මුල්ගල තියනවා වගේ දෙයක්. ඒ තමයි Constructors, විශේෂයෙන්ම Python වලදී අපි දකින __init__ method එකයි, ඒකත් එක්කම එන Instance Variables කියන දේයි.

ඔයාලා කලින් OOP ගැන දන්නවා නම්, Classes, Objects ගැන අහලා ඇති. හැබැයි මේ __init__ කියන method එක නැතුව හරියට වැඩක් කරන්න අමාරුයි. ඒ වගේම Instance Variables කියන්නේ අපේ Object එකටම ආවේණික දත්ත ගබඩා කරගන්න පුලුවන් තැන්. අද අපි මේ දෙකම හොඳටම තේරුම් අරගෙන, Code කරලා බලමු.

__init__ කියන්නේ මොකක්ද මේ?

හරි, මුලින්ම බලමු මේ __init__ කියන්නේ මොකක්ද කියලා. සරලවම කිව්වොත්, මේක විශේෂ method එකක්. Python වලදී මේකට කියනවා "Constructor" කියලා. දැන් Constructor කියන්නේ මොකක්ද? අපි Class එකකින් Object එකක් හදන හැම වෙලාවකම, මේ __init__ method එක automatic (නොදැනීම) call වෙනවා. ඒ කියන්නේ, අපිට ඕන කරන දේවල් Object එක හැදෙන ගමන්ම හදන්න, initialize කරන්න, මේක පාවිච්චි කරන්න පුළුවන්.

උදාහරණයක් විදියට අපි Car Class එකක් හදනවා කියලා හිතමු. Car එකක් හදනකොට ඒකට Model එකක්, Color එකක්, Year එකක් වගේ දේවල් මුලින්ම දෙන්න ඕනේනේ. මේ __init__ method එක හරහා අපිට පුළුවන් Object එක හැදෙන වෙලාවෙම මේවා දීලා, ඒ Object එකටම අදාළ (specific) වෙන විදියට මේ Variables ටික set කරන්න.

class MyClass:
    def __init__(self, argument1, argument2):
        # මේක තමයි constructor එක
        # Object එකක් හැදෙනකොට මේක automatically call වෙනවා
        print("Object එකක් හැදුවා!")
        self.attr1 = argument1
        self.attr2 = argument2

# MyClass එකෙන් Object එකක් හදමු
my_object = MyClass("හෙලෝ", 123) # __init__ method එක call වෙනවා
print(my_object.attr1)
print(my_object.attr2)

මේකේ තියෙන self කියන එක ගැන ඔයාලට ගැටලුවක් එන්න පුළුවන්. self කියන්නේ දැන් හැදෙන Object එකටම (instance) අදාළ වෙන එක. ඒ කියන්නේ, අපි my_object = MyClass("හෙලෝ", 123) කියලා Object එකක් හැදුවම, __init__ method එක ඇතුලේ self කියන්නේ අර my_object කියන එකටමයි. ඒක හරියට "මේ Object එකේම" කියන එක වගේ. ඕක අමතක කරන්න එපා, ඒක වැදගත්.

Instance Variables හැදෙන්නේ කොහොමද?

දැන් අපි කතා කරමු Instance Variables ගැන. මේවා කියන්නේ, Class එකක හැම Object එකකටම වෙන වෙනම තියාගන්න පුළුවන් Data (දත්ත) වගයක්. Class Variables කියලා තව ඒවා තියෙනවා, ඒක Class එකේ හැම Object එකටම පොදුයි. හැබැයි Instance Variables කියන්නේ, ඔයා Car Object දෙකක් හැදුවොත්, එක Car එකක Color එක Red වෙන්න පුළුවන්, අනිත් Car එකේ Color එක Blue වෙන්න පුළුවන්. මේ දෙකම color කියන Instance Variable එකෙන් නිරූපණය වුණත්, ඒ දත්ත දෙක Object එකෙන් Object එකට වෙනස් වෙනවා.

__init__ method එක ඇතුලෙදී අපි self.variable_name = value කියලා දාන හැම එකක්ම Instance Variables විදියටයි හැදෙන්නේ. Object එක හැදෙන ගමන්ම අපිට මේ Variables වලට අගයන් දෙන්න පුළුවන් නිසා, වැඩේ ගොඩක් පහසු වෙනවා.

class Person:
    def __init__(self, name, age):
        self.name = name  # Instance Variable
        self.age = age    # Instance Variable
        self.has_job = False # Default value for an instance variable

# Person Object දෙකක් හදමු
person1 = Person("කමල්", 30)
person2 = Person("නිරෝෂා", 25)

print(f"{person1.name} ට වයස {person1.age}යි.")
print(f"{person2.name} ට වයස {person2.age}යි.")

person1.has_job = True # Person1 ගේ has_job එක විතරක් වෙනස් කරනවා
print(f"{person1.name} ට රස්සාවක් තියෙනවද?: {person1.has_job}")
print(f"{person2.name} ට රස්සාවක් තියෙනවද?: {person2.has_job}")

මේ උදාහරණයෙන් පේනවා ඇති, person1 සහ person2 කියන Object දෙකටම වෙන වෙනම name, age, has_job කියන Instance Variables තියෙනවා. එකක වෙනසක් කලාට අනිත් එකට බලපාන්නේ නැහැ.

Car Class එකට __init__ එකක් දාමු

හරි, දැන් අපි අපේ Car Class එකට මේ __init__ method එක එකතු කරලා බලමු. මේක කලින් සරලව තිබ්බ Car Class එකක් කියලා හිතමු:

# කලින් තිබ්බ සරල Car Class එක
class Car:
    pass # මුකුත් නෑ

my_car = Car()
# මේකේ Model, Color වගේ දේවල් set කරන්න බෑ හරියට
# my_car.model = "Toyota" # මේක කරන්න පුළුවන් වුනත්, හොඳ practice එකක් නෙවෙයි

දැන් අපි මේකට __init__ එකක් දාමු, Car එකක් හදනකොටම ඒකට Model, Color, Year වගේ දේවල් දෙන්න පුළුවන් වෙන්න.

class Car:
    def __init__(self, model, color, year):
        self.model = model
        self.color = color
        self.year = year
        self.speed = 0 # Default value for a new car

    def accelerate(self, increment):
        self.speed += increment
        print(f"The {self.model} is now at {self.speed} km/h.")

    def get_info():
        # self argument is missing here. This will cause an error.
        # Corrected method below:
        # return f"This is a {self.year} {self.color} {self.model}."
        pass

    # Corrected get_info method
    def get_info(self):
        return f"This is a {self.year} {self.color} {self.model}."

# Car Objects හදමු
car1 = Car("Toyota Corolla", "White", 2020)
car2 = Car("Honda Civic", "Blue", 2022)

print(car1.get_info())
print(car2.get_info())

car1.accelerate(50)
car2.accelerate(70)

print(f"Car 1 speed: {car1.speed}")
print(f"Car 2 speed: {car2.speed}")



දැන් බලන්න, car1 සහ car2 කියන Object දෙක හදනකොටම අපි ඒවට Model, Color, Year දුන්නා. ඒ දේවල් ඒ Object වලටම අදාළ Instance Variables විදියට ගබඩා වුණා. speed කියන එකත් __init__ එක ඇතුලෙම 0 විදියට initialize කරලා තියෙන්නේ, මොකද අලුත් Car එකක speed එක 0 නේ. ඊට පස්සේ අපි accelerate method එක call කරලා ඒ ඒ Car වල speed එක වෙන වෙනම වෙනස් කලා. වැඩේ නියමෙටම සිද්ධ වුණා නේද?

පොඩි වැරදි (Common Mistakes)

මේ __init__ method එක පාවිච්චි කරනකොට beginner කෙනෙක්ට වෙන්න පුළුවන් පොඩි පොඩි වැරදි කිහිපයක් තියෙනවා. මේවා ගැන අවධානයෙන් ඉන්න.

1. self අමතක වීම

__init__ method එකේ පළවෙනි parameter එක විදියට self දෙන්න අමතක වෙනවා. මේක අමතක වුණොත් Python error එකක් දෙනවා.

class MyBadClass:
    # වැරදියි! self නැහැ
    def __init__(model, color): # 'self' is missing here
        # self.model = model # මේකත් self නැති නිසා error එකක් දෙනවා
        pass

# my_object = MyBadClass("Test", "Red") # මේක TypeError එකක් දෙනවා

TypeError: __init__() missing 1 required positional argument: 'color' වගේ error එකක් එයි. මොකද Python හිතන්නේ model කියන්නේ self කියලා, ඊට පස්සේ color කියන එකට අගයක් එන්නේ නැති නිසා.

2. Arguments ගණන වැරදීම

__init__ method එකට දෙන Arguments ගණන, Object එක හදනකොට දෙන Arguments ගණනට සමාන වෙන්න ඕනේ. අඩු වුනත් වැඩි වුනත් error එකක් එනවා.

class AnotherCar:
    def __init__(self, model, color):
        self.model = model
        self.color = color

# car3 = AnotherCar("Perodua Kancil") # Error: missing 1 required positional argument: 'color'
# car4 = AnotherCar("Audi", "Black", 2023) # Error: takes 3 positional arguments but 4 were given

මේ වගේ තැන් වලදී traceback එක හොඳට කියවලා බලන්න. එතකොට තේරෙයි මොකක්ද වෙලා තියෙන්නේ කියලා.

Best Practices: නියම විදියට වැඩේ කරමු

OOP වලදී, විශේෂයෙන්ම Python වලදී, හොඳ practice එකක් තමයි Class එකක හැම Instance Variable එකක්ම __init__ method එක ඇතුලෙම initialize කරන එක. ඒ කියන්නේ, Object එකක් හැදෙන ගමන්ම ඒකේ තියෙන්න ඕන හැම අගයක්ම __init__ එකෙන් සකස් කරන එක.

ඇයි මේක වැදගත්? හේතු කීපයක් තියෙනවා:

  1. Clarity (පැහැදිලි බව): Class එකක් දිහා බලපු ගමන්, ඒ Object එකක තියෙන Variables මොනවද, ඒවට මුල් අගයන් කොහොමද එන්නේ කියලා අපිට පැහැදිලිව පේනවා.
  2. Consistency (අනුකූලතාවය): හැම Object එකක්ම එකම විදියට initialize වෙනවා. සමහර Object වල Variable එකක් තියෙනවා, සමහර ඒවායේ නැහැ වගේ අවුල් තත්වයක් ඇති වෙන්නේ නැහැ.
  3. Debugging (වැරදි සොයා ගැනීම): Variable එකක් කොතනින්ද ආවේ කියලා හොයන්න ලේසියි. Object එක හැදුන ගමන් ඒකට අගයක් ලැබිලා තියෙනවාද කියලා බලන්න __init__ එක check කරන්න පුළුවන්.
class Laptop:
    def __init__(self, brand, model, ram_gb, storage_gb, is_on=False):
        self.brand = brand
        self.model = model
        self.ram_gb = ram_gb
        self.storage_gb = storage_gb
        self.is_on = is_on # Default value for 'is_on'

    def turn_on(self):
        if not self.is_on:
            self.is_on = True
            print(f"The {self.brand} {self.model} is now ON.")
        else:
            print(f"The {self.brand} {self.model} is already ON.")

    def get_specs(self):
        return f"{self.brand} {self.model} with {self.ram_gb}GB RAM and {self.storage_gb}GB storage."

laptop1 = Laptop("HP", "ProBook", 16, 512)
laptop2 = Laptop("Dell", "XPS 15", 32, 1024, True) # Initializing 'is_on' as True

print(laptop1.get_specs())
print(f"Laptop 1 is on: {laptop1.is_on}")
laptop1.turn_on()
print(f"Laptop 1 is on: {laptop1.is_on}")

print("\n")

print(laptop2.get_specs())
print(f"Laptop 2 is on: {laptop2.is_on}")
laptop2.turn_on() # Already on

මේ Laptop Class එකේ is_on කියන Variable එකට default value එකක් දීලා තියෙනවා False කියලා. හැබැයි අපි Object එකක් හදනකොට ඒක True කරන්න ඕනේ නම්, ඒකත් Arguments විදියටම දෙන්න පුළුවන්. මේ වගේ දේවල් වලදී Default Arguments පාවිච්චි කරන එකත් ගොඩක් හොඳ practice එකක්.

අවසාන වචන

ඉතින් යාලුවනේ, අද අපි Python OOP වල හදවත වගේ වෙන __init__ method එකයි, Instance Variables කියන සංකල්පයයි හොඳටම ඉගෙන ගත්තා. මේක හරියට software engineering ගමනේදී අපිට හම්බවෙන වැදගත් සන්ධිස්ථානයක් වගේ. මේක නැතුව හරියට Object-Oriented Programs ලියන්න බැහැ.

මතක තියාගන්න, තේරුම් ගන්න හොඳම විදිය තමයි code කරලා බලන එක. ඔයාලත් මේ උදාහරණ ටික modify කරලා, තමන්ට ඕන විදියට Class හදලා, __init__ එකයි Instance Variables ටිකයි පාවිච්චි කරලා බලන්න. Car Class එකට අලුත් attributes එකතු කරන්න, methods එකතු කරන්න, අලුත් objects හදලා බලන්න.

මේ ගැන ඔයාලට මොනවා හරි ප්‍රශ්න තියෙනවා නම්, හරි එහෙම නැත්තම් මේකෙදි මගෙන් වැරදුන තැනක් හරි, තව හොඳට පැහැදිලි කරන්න පුලුවන් තැනක් හරි තියෙනවා නම්, පහලින් comment එකක් දාන්න. අපි ඒ ගැන කතා කරමු. ඊළඟ ලිපියෙන් හම්බවෙමු! සුබ දවසක්!