Наведено абстрактний клас камери, яка характеризується розміром кадру. В класі передбачено можливість фотографування та масштабування зображення.
Для прикладу наведено методи get/set для поля __frameSize
та властивість (@property
) в стилі Python
class PhotoCamera:
def __init__(self, frameSize):
self.__frameSize = frameSize
self._image = None
def getFrameSize(self):
"""So-called getter"""
return self.__frameSize
def setFrameSize(self, frameSize):
self.__frameSize = frameSize
@property
def frameSize(self):
"""Property of the object"""
return self.__frameSize
def makeShot(self, image):
pass
def zoom(self, scale):
pass
camera = PhotoCamera([1024, 768])
print(camera.getFrameSize())
print(camera.frameSize)
[1024, 768] [1024, 768]
Звертання до приватного поля напряму заборонено:
print(camera.__frameSize)
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [3], in <cell line: 1>() ----> 1 print(camera.__frameSize) AttributeError: 'PhotoCamera' object has no attribute '__frameSize'
Конкретний клас камери, який реалізує абстрактний клас PhotoCamera
class NikonCamera(PhotoCamera):
def __init__(self, matrixSize):
self.__matrixSize = matrixSize
def makeShot(self, image):
self._image = image
print('Click at {}!'.format(self._image))
def zoom(self, scale):
self._image /= scale
nikon = NikonCamera(0.5)
nikon.makeShot(49545654)
Click at 49545654!
Інший конкретний клас, який містить власну реалізацію методів камери:
class BlenderCamera(PhotoCamera):
def __init__(self, position, direction):
self.__position = position
self.__direction = direction
def makeShot(self, image):
self._image = image
print('Render from position {} with direction {} is done!'.format(self.__position, self.__direction))
def zoom(self, scale):
self._image /= scale
blender = BlenderCamera([10, 2, 4], [45, 15])
blender.makeShot(84549)
Render from position [10, 2, 4] with direction [45, 15] is done!
Поліморфізм: маємо список об'єктів, всі з яких реалізують клас PhotoCamera
, тому можна звертатися до їх методу makeShot
, який імплементовано по-різному в кожного з об'єктів
blender2 = BlenderCamera([85, 35, -38], [90, 0])
mycameras = [nikon, blender, blender2]
for cam in mycameras:
cam.makeShot(844554)
Click at 844554! Render from position [10, 2, 4] with direction [45, 15] is done! Render from position [85, 35, -38] with direction [90, 0] is done!
Наявність об'єкту іншого типу "ламає" код:
mycameras = [nikon, blender, blender2, [6, 3, 5]]
for cam in mycameras:
cam.makeShot(844554)
Click at 844554! Render from position [10, 2, 4] with direction [45, 15] is done! Render from position [85, 35, -38] with direction [90, 0] is done!
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [9], in <cell line: 2>() 1 mycameras = [nikon, blender, blender2, [6, 3, 5]] 2 for cam in mycameras: ----> 3 cam.makeShot(844554) AttributeError: 'list' object has no attribute 'makeShot'
Приклад роботи з виключенням (exception) для відслідковування недопустимих аргументів методів:
class NikonCameraWithException(PhotoCamera):
def __init__(self, matrixSize):
self.__matrixSize = matrixSize
def makeShot(self, image):
self._image = image
print('Click at {}!'.format(self._image))
def zoom(self, scale):
if scale >= 0.5 and scale <= 10:
self._image /= scale
else:
raise ValueError('Scale should be within [0.5...10]!')
nikon.zoom(10)
nikon.zoom(0)
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) Input In [12], in <cell line: 1>() ----> 1 nikon.zoom(0) Input In [4], in NikonCamera.zoom(self, scale) 9 def zoom(self, scale): ---> 10 self._image /= scale ZeroDivisionError: float division by zero
nikon2 = NikonCameraWithException(0.5)
nikon2.makeShot(48456)
nikon2.zoom(5)
Click at 48456!
nikon2.zoom(0.05)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [14], in <cell line: 1>() ----> 1 nikon2.zoom(0.05) Input In [10], in NikonCameraWithException.zoom(self, scale) 11 self._image /= scale 12 else: ---> 13 raise ValueError('Scale should be within [0.5...10]!') ValueError: Scale should be within [0.5...10]!
try:
nikon2.zoom(0.05)
except:
print('Wrong zoom was used')
Wrong zoom was used