For example, you can define the abstract getter, setter and deleter with @abstractmethod
and @property
, @name.setter
or @name.deleter
in Person
abstract class as shown below. *@abstractmethod
must be the innermost decorator otherwise error occurs:
from abc import ABC, abstractmethod
class Person(ABC):
@property
@abstractmethod # The innermost decorator
def name(self): # Abstract getter
pass
@name.setter
@abstractmethod # The innermost decorator
def name(self, name): # Abstract setter
pass
@name.deleter
@abstractmethod # The innermost decorator
def name(self): # Abstract deleter
pass
Then, you can extend Person
abstract class with Student
class, override the abstract getter, setter and deleter in Student
class, instantiate Student
class and call the getter, setter and deleter as shown below:
class Student(Person):
def __init__(self, name):
self._name = name
@property
def name(self): # Overrides abstract getter
return self._name
@name.setter
def name(self, name): # Overrides abstract setter
self._name = name
@name.deleter
def name(self): # Overrides abstract deleter
del self._name
obj = Student("John") # Instantiates "Student" class
print(obj.name) # Getter
obj.name = "Tom" # Setter
print(obj.name) # Getter
del obj.name # Deleter
print(hasattr(obj, "name"))
Output:
John
Tom
False
Actually, even if you don't override the abstract setter and deleter in Student
class and instantiate Student
class as shown below:
class Student(Person): # Extends "Person" class
def __init__(self, name):
self._name = name
@property
def name(self): # Overrides only abstract getter
return self._name
# @name.setter
# def name(self, name): # Overrides abstract setter
# self._name = name
# @name.deleter
# def name(self): # Overrides abstract deleter
# del self._name
obj = Student("John") # Instantiates "Student" class
# ...
No error occurs as shown below:
John
Tom
False
But, if you don't override the abstract getter, setter and deleter in Student
class and instantiate Student
class as shown below:
class Student(Person): # Extends "Person" class
def __init__(self, name):
self._name = name
# @property
# def name(self): # Overrides only abstract getter
# return self._name
# @name.setter
# def name(self, name): # Overrides abstract setter
# self._name = name
# @name.deleter
# def name(self): # Overrides abstract deleter
# del self._name
obj = Student("John") # Instantiates "Student" class
# ...
The error below occurs:
TypeError: Can't instantiate abstract class Student with abstract methods name
And, if you don't override the abstract getter in Student
class and instantiate Student
class as shown below:
class Student(Person): # Extends "Person" class
def __init__(self, name):
self._name = name
# @property
# def name(self): # Overrides only abstract getter
# return self._name
@name.setter
def name(self, name): # Overrides abstract setter
self._name = name
@name.deleter
def name(self): # Overrides abstract deleter
del self._name
obj = Student("John") # Instantiates "Student" class
# ...
The error below occurs:
NameError: name 'name' is not defined
And, if @abstractmethod
is not the innermost decorator as shown below:
from abc import ABC, abstractmethod
class Person(ABC):
@abstractmethod # Not the innermost decorator
@property
def name(self): # Abstract getter
pass
@name.setter
@abstractmethod # The innermost decorator
def name(self, name): # Abstract setter
pass
@name.deleter
@abstractmethod # The innermost decorator
def name(self): # Abstract deleter
pass
The error below occurs:
AttributeError: attribute 'isabstractmethod' of 'property' objects is not writable
@property
inclass C
,name
will revert to a method. – Orthorhombic