class Avto:
def __init__(self, model="06", owner="Մեքենա մեքենիկյան", secret="չեմ ասի"):
self.model = model # public
self._owner = owner # protected
self.__secret = secret # private
print(self.model, self._owner, self.__secret)
16 OOP 3: Encapsulation, Abstraction
Երևան, Մոսկովյան, լուսանկարի հղումը, Հեղինակ՝ Taguhi Kirakosyan
Song reference - ToDo
🎦 Տեսադասեր + լրացուցիչ (ToDo)
ToDo 1. Տեսություն 2025
2. Տեսություն 2023 (ToDo)
3. Գործնական 2025
4. Գործնական 2023 (ToDo)
5. Որոշ տնայինների լուծումներ (ToDo)
Google Forms ToDo
📚 Նյութը
Encapsulation (նույն ինքը՝ “քեզ ինչ”)
https://www.datacamp.com/tutorial/encapsulation-in-python-object-oriented-programming
Feature | Python | Java | C++ |
---|---|---|---|
Access modifiers | No enforced modifiers; uses naming conventions (_protected, __private) | Enforced with public, protected, private keywords | Enforced with public, protected, private keywords |
Getter/setter methods | Optional, often used with @property decorator for controlled access | Common practice, typically implemented as methods | Common practice, typically implemented as methods |
Data Access | Accessible via naming conventions; relies on developer discipline | Controlled by access modifiers; enforced by the compiler | Controlled by access modifiers; enforced by the compiler |
Philosophy | “We are all adults here” - relies on conventions and trust | Strict enforcement of access control | Strict enforcement of access control |
Public, Protected, Private
Level | Prefix | Enforcement | Use Case |
---|---|---|---|
Public | none | None | Functions & data meant for everyone |
Protected | _single |
Convention | Internal helpers, subclass support |
Private | __double |
Name-mangling | Strictly internal, avoid subclass clashes |
Public
= Avto()
jiguli
print(jiguli.model)
= "07"
jiguli.model
print(jiguli.model)
06 Մեքենա մեքենիկյան չեմ ասի
06
07
Protected
= Avto()
jiguli
print(jiguli._owner)
= ""
jiguli._owner
print(jiguli._owner)
06 Մեքենա մեքենիկյան չեմ ասի
Մեքենա մեքենիկյան
Private (name mangling)
ոնց-որ թե հազիվ ձև գտանք, բայց իրականում նույն չափ էֆեկտիվ մեթոդ ա ինչ հայտարարելը “շուտ եմ ասել, ով էս փոփոխականի հետ գործ արեց փիղ ա”
= Avto()
jiguli
print(jiguli.__secret)
# jiguli.__secret = "Մեքենայատեր Տերյան"
# print(jiguli.__secret)
06 Մեքենա մեքենիկյան չեմ ասի
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [5], in <cell line: 3>() 1 jiguli = Avto() ----> 3 print(jiguli.__secret) 5 # jiguli.__secret = "Մեքենայատեր Տերյան" 6 7 # print(jiguli.__secret) AttributeError: 'Avto' object has no attribute '__secret'
dir(jiguli)
['_Avto__secret',
'__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'_owner',
'model']
= Avto()
jiguli
print(jiguli._Avto__secret)
= "Մեքենայատեր Տերյան"
jiguli._Avto__secret
print(jiguli._Avto__secret)
06 Մեքենա մեքենիկյան չեմ ասի
չեմ ասի
Մեքենայատեր Տերյան
Getter, setter, deleter-ներ
Մենք ուզում ենք ինչքան հնարավորա ուրիշներին ասենք հեռու մնացեք մեր կոդից, ձեզ մենակ էս-էս բաներն ենք տրամադրում
եթե ուզում են ինչ-որ փոփոպականի կպնեն ու հետը փոփոխություն անեն ինչ-որ ոչ թե թույլ կտանք ուղիղ հենց իրա հետ գործ անեն ու ինչ-որ բան ջարդեն կամ տեսնեն ինչ-որ բան որն իրանց աչքերի համար չէր, այլ ասենք ուզում ես արժեքը ստանաս, խնդիր չկա կանչի էս ֆունկցիան՝ կտա, ուզում ես արժեք փոխես (ու սխալ մուտք տաս կոդը ջարդես), տուր արժեքդ մենք կփոխենք
class Avto:
def __init__(self, model="06", owner="Մեքենա մեքենիկյան", secret="չեմ ասի"):
self.model = model
self._owner = owner
self.__secret = secret
def info(self):
= f"{self.model} {self._owner.capitalize()}, {self.__secret}"
text return text
= Avto()
jiguli
print(jiguli.info())
print(jiguli._owner)
= 1
jiguli._owner
print(jiguli.info())
06 Մեքենա մեքենիկյան, չեմ ասի
Մեքենա մեքենիկյան
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [9], in <cell line: 9>() 5 print(jiguli._owner) 7 jiguli._owner = 1 ----> 9 print(jiguli.info()) Input In [8], in Avto.info(self) 7 def info(self): ----> 8 text = f"{self.model} {self._owner.capitalize()}, {self.__secret}" 9 return text AttributeError: 'int' object has no attribute 'capitalize'
class Avto:
def __init__(self, model="06", owner="Մեքենա մեքենիկյան", secret="չեմ ասի"):
self.model = model
self._owner = owner
self.__secret = secret
def info(self):
= f"{self.model} {self._owner.capitalize()}, {self.__secret}"
text return text
def get_owner(self):
return self._owner
def set_owner(self, value):
if isinstance(value, str):
self._owner = value
else:
# self._owner = str(value)
raise ValueError("Անուն տուր ոչ թե թիվ")
def del_owner(self):
print("Մեքենայի տիրոջ անունը ջնջում եմ")
del self._owner
= Avto()
jiguli
print(jiguli.info())
print(jiguli.get_owner())
1)
jiguli.set_owner(
# # jiguli.set_owner("Ավտո Վուվույան")
# print(jiguli.info())
# jiguli.del_owner()
# print(jiguli.info())
06 Մեքենա մեքենիկյան, չեմ ասի
Մեքենա մեքենիկյան
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [12], in <cell line: 7>() 3 print(jiguli.info()) 5 print(jiguli.get_owner()) ----> 7 jiguli.set_owner(1) 8 # # jiguli.set_owner("Ավտո Վուվույան") 9 10 # print(jiguli.info()) (...) 13 14 # print(jiguli.info()) Input In [10], in Avto.set_owner(self, value) 16 self._owner = value 17 else: 18 # self._owner = str(value) ---> 19 raise ValueError("Անուն տուր ոչ թե թիվ") ValueError: Անուն տուր ոչ թե թիվ
Property decorator
Բայց ախր շատ անհարմարա սենց ֆունկցիաների անուններ գրել երկար ամեն անգամ ֆունկցիա աշխատացնել, լավ էր էլի որ գրում էինք ուղղակի jiguli._owner = ․․
"aaa")
jiguli.set_owner(= "aaa" jiguli._owner
class Avto:
def __init__(self, model="06", owner="Մեքենա մեքենիկյան", secret="չեմ ասի"):
self.model = model
self._owner = owner
self.__secret = secret
def info(self):
= f"{self.model}"
text return text
@property
def owner(self):
return self._owner
@owner.setter
def owner(self, value):
if isinstance(value, str):
self._owner = value
else:
raise ValueError("անուն տուր ոչ թե թիվ")
@owner.deleter
def owner(self):
print("ջնջում եմ")
del self._owner
= Avto()
jiguli
print(jiguli.info())
print(jiguli.owner) # Using getter
06
Մեքենա մեքենիկյան
= "Ավտո Վուվույան" # Using setter # jiguli.set_owner("Ավտո ․․․")
jiguli.owner del jiguli.owner # jiguli.delete_owner()
ջնջում եմ
del jiguli.model
Եթե owner-ը protected չլիներ։
class Avto:
def __init__(self, model="06", owner="Մեքենա մեքենիկյան", secret="չեմ ասի"):
self.model = model
self._owner = owner
self.__secret = secret
@property
def owner(self):
return self.owner
def _gaxtni_info(self):
= Avto() #յիգւլի․owner
jiguli
= 3 jiguli._owner
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [11], in <cell line: 3>() 1 jiguli = Avto() #յիգւլի․owner ----> 3 jiguli.owner = 3 AttributeError: can't set attribute 'owner'
Abstraction
Abstraction is the process of hiding the complex reality while exposing only the necessary parts. In code, it lets you:
- Simplify by focusing on “what” something does, not “how” it does it.
- Encapsulate complexity behind a clean interface.
- Promote reuse and flexibility by decoupling implementation from usage.
import os
class FileReader:
def __init__(self, path):
self.path = path
self.size = self.get_size()
self.text = None
def get_size(self):
return os.stat(self.path).st_size
def read(self):
# pass
raise NotImplementedError
def write(self):
# pass
raise NotImplementedError
class TextReader(FileReader):
def read(self):
if self.text is None:
with open(self.path, "r") as f:
self.text = f.read()
return self.text
with open("a.txt", "w") as f:
"Շուդադի շուդադա վիզաութ յո լավ, վեդեֆոյու, վեդեֆոյու") f.write(
= TextReader("a.txt") t
t.get_size()
96
t.write()
--------------------------------------------------------------------------- NotImplementedError Traceback (most recent call last) Input In [18], in <cell line: 1>() ----> 1 t.write() Input In [13], in FileReader.write(self) 16 def write(self): 17 # pass ---> 18 raise NotImplementedError NotImplementedError:
ուզում ենք աշխատացնենք write-ը, TextReader-ը չունի, գնում ա կանչում ա FileReader-ինը իսկ ընդեղ գրած ա որ էռոռ ա բարձրացնում որովհետև գրված չի մեթոդի կոդը
Լավ կլիներ բայց որ եթե writeը ֆունդամենտալ մասա կլասի, ու առանց իրա պետքա կլասը գոյություն ունենա նենց անենք որ կլասից ժառանգողը ստիպված լինի սահմանի էդ մեթոդը
Abstract methods
from abc import ABC, abstractmethod
# ձևանմուշ (template)
class FileReader(ABC): # Abstract Base Class
def __init__(self, path):
self.path = path
self.size = self.get_size()
self.text = None
def get_size(self):
return os.stat(self.path).st_size
@abstractmethod
def read(self):
pass
@abstractmethod
def write(self):
pass
class TextReader(FileReader):
def read(self):
if self.text is None:
with open(self.path, "r") as f:
self.text = f.read()
return self.text
= TextReader("a.txt") t
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [26], in <cell line: 1>() ----> 1 t = TextReader("a.txt") TypeError: Can't instantiate abstract class TextReader with abstract method write
class TextReader(FileReader):
def read(self):
if self.text is None:
with open(self.path, "r") as f:
self.text = f.read()
return self.text
def write(self):
# pass
print("էլ չի ջարդվում կոդը")
= TextReader("a.txt")
t
t.write()
էլ չի ջարդվում կոդը
# class JsonReader
class Model: # algorithm
@abstractmethod
def read_data # fit
@abstractmethod
def predict():
pass
# .fit
# .predict
Abstract variables
class FileReader(ABC):
def __init__(self, path):
self.path = path
self.size = self.get_size()
self.text = None
@property
@abstractmethod
def description(self):
pass
def get_size(self):
return os.stat(self.path).st_size
@abstractmethod
def read(self):
pass
@abstractmethod
def write(self):
pass
class TextReader(FileReader):
def read(self):
if self.text is None:
with open(self.path, "r") as f:
self.text = f.read()
return self.text
def write(self):
print("էլ չի ջարդվում կոդը")
= "1"
description # @property
# def description(self):
# return "Սևանը չէ՞"
= TextReader("a.txt")
t
t.description
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [41], in <cell line: 1>() ----> 1 t = TextReader("a.txt") 3 t.description TypeError: Can't instantiate abstract class TextReader with abstract method description