Python allows you to create your own data types using classes, first however lets look at types, you can use the type command to see what type an object is and also to compare objects. One feature of python is Duck typing, Duck typing is a concept related to dynamic typing, where the type or the class of an object is less important than the methods it defines. When you use duck typing, you do not check types at all. Instead, you check for the presence of a given method or attribute.
| Types of an object | print(type(5)) # int
print(type("Hello")) # str
print(type(['Hello','World'])) # list
print(type("Hello") == type("World")) # true as both are str type
print(isinstance("Hello", str)) # true as "hello" is a str type |
| Comparing objects | class A:
pass
class B(A):
pass
b = B()
print(type(b)) # results in <class '__main__.B'>
print(b.__class__) # same as above
print(isinstance(b, (B))) # True, as b is an instance of class B |
A special method attribute is an attribute of a class that has s special meaning, it is defined as a method normally they are automatically invoke in response to a demend made on an object of that class. The simplest is the __str__ which acts like the toString() in Java, if you use print on the object name the __str__ is called and thus is used to display the data inside the object in a readable format.
There are many special methods and I will demostrate a few below but see the Python documentation for a full list.
| __str__ example | class Employee:
def __init__(self, fname, lname):
self.fname = fname
self.lname = lname
def __str__(self):
return "Name is {0} {1}".format(self.fname, self.lname)
emp1 = Employee("Paul","Valle")
print(emp1) # uses the __str__ to display object |
The magic method __getitem__ is basically used for accessing list items, dictionary entries, array elements etc. It is very useful for a quick lookup of instance attributes, you also have __setitem__ which sets list items, etc.
| __getitem__ and __setitem__ example | class Employees:
def __init__(self, employees):
self.employees = [None]*employees
def __setitem__(self, employee_number, value):
self.employees[employee_number] = value
def __getitem__(self, employee_number):
return "Employee: " + self.employees[employee_number]
company_employees = Employees(4) # uses the __init__
company_employees[0] = "Paul Valle" # will use the __setitem__
company_employees[1] = "Will Hay" # will use the __setitem__
company_employees[2] = "Moore Marriott" # will use the __setitem__
company_employees[3] = "Graham Moffatt" # will use the __setitem__
print(company_employees[0]) # will use the __getitem__
print(company_employees[1]) # will use the __getitem__
print(company_employees[2]) # will use the __getitem__
print(company_employees[3]) # will use the __getitem__ |
The magic method __del__ is used for cleanup and is called when the object is garbage collected
| __del__ example | class Dummy1:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def __del__(self): # is called when object is garbage collected
print("Called if object is deleted or garage collected,used for cleanup")
d = Dummy1("Paul Valle")
print(d)
## __del__ will get called here when program terminates |