0% found this document useful (0 votes)
392 views

Descriptor

The document describes how to create descriptors and properties in Python to manage attributes, including defining descriptor and property classes to validate attribute values, as well as using property decorators. It provides examples of creating descriptors and properties to manage employee ID and name attributes on an Employee class.

Uploaded by

roy.scar2196
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
392 views

Descriptor

The document describes how to create descriptors and properties in Python to manage attributes, including defining descriptor and property classes to validate attribute values, as well as using property decorators. It provides examples of creating descriptors and properties to manage employee ID and name attributes on an Employee class.

Uploaded by

roy.scar2196
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

Descriptors - Example

Example 1

class EmpNameDescriptor:
def __get__(self, obj, owner):
return self.__empname
def __set__(self, obj, value):
if not isinstance(value, str):
raise TypeError("'empname' must be a string.")
self.__empname = value
The descriptor, EmpNameDescriptor is defined to manage empname attribute.

It checks if the value of empname attribute is a string or not.

Descriptors - Example...
Example 1...

class EmpIdDescriptor:
def __get__(self, obj, owner):
return self.__empid
def __set__(self, obj, value):
if hasattr(obj, 'empid'):
raise ValueError("'empid' is read only attribute")
if not isinstance(value, int):
raise TypeError("'empid' must be an integer.")
self.__empid = value
The descriptor, EmpIdDescriptor is defined to manage empid attribute.

Descriptors - Example...
Example 1...

class Employee:
empid = EmpIdDescriptor()
empname = EmpNameDescriptor()
def __init__(self, emp_id, emp_name):
self.empid = emp_id
self.empname = emp_name
Employee class is defined such that, it creates empid and empname attributes from
descriptors EmpIdDescriptor and EmpNameDescriptor.

Descriptors - Example...
Example 1...

e1 = Employee(123456, 'John')
print(e1.empid, '-', e1.empname)
e1.empname = 'Williams'
print(e1.empid, '-', e1.empname)
e1.empid = 76347322
You can observe that accessing attributes empid and empname appear as if you are
accessing them directly.

However when executing the expression e1.empid = 76347322, the __set__ method
defined in EmpIdDescriptor is executed and raises "ValueError: 'empid' is read only
attribute".

Properties
Descriptors can also be created using property() type.

It is easy to create a descriptor for any attribute using property().


Syntax of defining a Property

property(fget=None, fset=None, fdel=None, doc=None)

where,

fget : attribute get method

fset : attribute set method

fdel – attribute delete method

doc – docstring

Properties - Example
Example 1

class Employee:
def __init__(self, emp_id, emp_name):
self.empid = emp_id
self.empname = emp_name
def getEmpID(self):
return self.__empid
def setEmpID(self, value):
if not isinstance(value, int):
raise TypeError("'empid' must be an integer.")
self.__empid = value
empid = property(getEmpID, setEmpID)
empid attribute created using property.

Properties - Example...
Example 1...

def getEmpName(self):

return self.__empname

def setEmpName(self, value):

if not isinstance(value, str):

raise TypeError("empname' must be a string.")

self.__empname = value

def delEmpName(self):

del self.__empname

empname = property(getEmpName, setEmpName, delEmpName)


empname attribute created using property. It is deleted when delEmpName method is
called.

Properties - Example...
Example 1...

e1 = Employee(123456, 'John')

print(e1.empid, '-', e1.empname) # -> '123456 - John'

del e1.empname # Deletes 'empname'

print(e1.empname) #Raises 'AttributeError'

Output

123456 - John

AttributeError: ...

When del e1.empname is executed, it in turn calls delEmpName method.

Hence accessing empname attribute after the del expression results in


AttributeError.

Property Decorators
Descriptors can also be created with property decorators.

While using property decorators, an attribute's get method will be same as its name
and will be decorated with property.

In a case of defining any set or delete methods, they will be decorated with
respective setter and deleter methods.

Property - Decorator...
Example 1

class Employee:
def __init__(self, emp_id, emp_name):
self.empid = emp_id
self.empname = emp_name
@property
def empid(self):
return self.__empid
@empid.setter
def empid(self, value):
if not isinstance(value, int):
raise TypeError("'empid' must be an integer.")
self.__empid = value
get and set methods of empid attribute are decorated with property.

Property - Decorator...
Example 1...

@property
def empname(self):
return self.__empname
@empname.setter
def empname(self, value):
if not isinstance(value, str):
raise TypeError("'empname' must be a string.")
self.__empname = value
@empname.deleter
def empname(self):
del self.__empname
get, set, and del methods of empname are decorated with property.

Property - Decorator...
Example 1...

e1 = Employee(123456, 'John')
print(e1.empid, '-', e1.empname) # -> '123456 - John'
del e1.empname # Deletes 'empname'
print(e1.empname) #Raises 'AttributeError'
Output
123456 - John
AttributeError : ...
deleter method corresponding to empname attribute is called when the expression,
del e1.empname is executed.

Q
#!/bin/python3

import sys
import os

# Add Celsius class implementation below.


class Celsius:
def __get__(self,obj,owner):
return self.__celsius
def __set__(self,obj,value):
self.__celsius = value

# Add temperature class implementation below.


class Temperature:
celsius = Celsius()
def __init__(self,value):
self.celsius = (value - 32) * 5 / 9
self.fahrenheit = value

'''Check the Tail section for input/output'''

if __name__ == "__main__":
with open(os.environ['OUTPUT_PATH'], 'w') as fout:
res_lst = list()
t1 = Temperature(int(input()))
res_lst.append((t1.fahrenheit, t1.celsius))
t1.celsius = int(input())
res_lst.append((float(t1.fahrenheit), float(t1.celsius)))
fout.write("{}\n{}".format(*res_lst))

You might also like