Python OOP Classes and Instances:
class Employee:
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
def fullname(self):
return '{} {}'.format(self.first, self.last)
emp_1 = Employee('Alex', 'Brown', 50000)
emp_2 = Employee('Lisa', 'Miller', 60000)
print(type(emp_1)) # <class '__main__.Employee'>
print(emp_1.email) # Alex.Brown@email.com
print(emp_2.fullname()) # Lisa Miller
print(Employee.fullname(emp_2)) # Lisa Miller
Python OOP Class Variables:
Class Variables shared for all instances of the class.
class Employee:
raise_amount = 1.04
num_of_emps = 0
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
Employee.num_of_emps += 1
def fullname(self):
return '{} {}'.format(self.first, self.last)
def apply_raise(self):
self.pay = int(self.pay * self.raise_amount)
emp_1 = Employee('Alex', 'Brown', 50000)
emp_2 = Employee('Lisa', 'Miller', 60000)
print(emp_1.raise_amount) # 1.04
print(Employee.raise_amount) # 1.04
print(emp_1.pay) # 50000
emp_1.apply_raise()
print(emp_1.pay) # 52000
Employee.raise_amount = 1.05
print(Employee.raise_amount) # 1.05
print(emp_2.raise_amount) # 1.05
emp_2.raise_amount = 1.07
print(emp_2.raise_amount) # 1.07
print(emp_1.__dict__)
# {'first': 'Alex', 'last': 'Brown', 'email': 'Alex.Brown@email.com', 'pay': 50000}
print(emp_2.__dict__)
# {'first': 'Lisa', 'last': 'Miller', 'email': 'Lisa.Miller@email.com', 'pay': 60000, 'raise_amount': 1.07}
print(Employee.__dict__)
# {'__module__': '__main__', 'raise_amount': 1.04, 'num_of_emps': 2,
# '__init__': <function Employee.__init__ at 0x000001F34784EF28>,
# 'fullname': <function Employee.fullname at 0x000001F347852048>,
# 'apply_raise': <function Employee.apply_raise at 0x000001F3478520D0>,
# '__dict__': <attribute '__dict__' of 'Employee' objects>,
# '__weakref__': <attribute '__weakref__' of 'Employee' objects>, '__doc__': None}
print(Employee.num_of_emps) # 2
Python OOP classmethods
class Employee:
raise_amount = 1.04
num_of_emps = 0
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
Employee.num_of_emps += 1
def fullname(self):
return '{} {}'.format(self.first, self.last)
def apply_raise(self):
self.pay = int(self.pay * self.raise_amount)
@classmethod
def set_raise_amount(cls, amount):
cls.raise_amount = amount
@classmethod
def from_string(cls, emp_str): # Alternative constructor
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
emp_1 = Employee('Alex', 'Brown', 50000)
emp_2 = Employee('Lisa', 'Miller', 60000)
print(Employee.raise_amount) # 1.04
print(emp_1.raise_amount) # 1.04
print(emp_2.raise_amount) # 1.04
Employee.set_raise_amount(1.05)
print(Employee.raise_amount) # 1.05
print(emp_1.raise_amount) # 1.05
print(emp_2.raise_amount) # 1.05
emp_3 = Employee.from_string('Bob-Fox-70000')
print(emp_3.fullname()) # Bob Fox
Python OOP staticmethods
class Employee:
raise_amount = 1.04
num_of_emps = 0
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
Employee.num_of_emps += 1
def fullname(self):
return '{} {}'.format(self.first, self.last)
def apply_raise(self):
self.pay = int(self.pay * self.raise_amount)
@classmethod
def set_raise_amount(cls, amount):
cls.raise_amount = amount
@classmethod
def from_string(cls, emp_str): # Alternative constructor
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
@staticmethod
def is_workday(day):
if day.weekday() == 5 or day.weekday() == 6: # Saturday or Sunday
return False
return True
emp_1 = Employee('Alex', 'Brown', 50000)
emp_2 = Employee('Lisa', 'Miller', 60000)
import datetime
my_date = datetime.date(2015,4,19)
print(Employee.is_workday(my_date)) # False
Python OOP Inheritance - Creating Subclasses
class Employee:
raise_amount = 1.04
num_of_emps = 0
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
Employee.num_of_emps += 1
def fullname(self):
return '{} {}'.format(self.first, self.last)
def apply_raise(self):
self.pay = int(self.pay * self.raise_amount)
@classmethod
def set_raise_amount(cls, amount):
cls.raise_amount = amount
@classmethod
def from_string(cls, emp_str): # Alternative constructor
first, last, pay = emp_str.split('-')
return cls(first, last, pay)
@staticmethod
def is_workday(day):
if day.weekday() == 5 or day.weekday() == 6: # Saturday or Sunday
return False
return True
class Developer(Employee):
raise_amount = 1.10
def __init__(self, first, last, pay, prog_lang):
super().__init__(first, last, pay)
# Employee.__init__(self, first, last, pay) # Same as before
self.prog_lang = prog_lang
class Manager(Employee):
def __init__(self, first, last, pay, employees=None):
super().__init__(first, last, pay)
if employees is None:
self.employees = []
else:
self.employees = employees
def add_emp(self, emp):
if emp not in self.employees:
self.employees.append(emp)
def del_emp(self, emp):
if emp in self.employees:
self.employees.remove(emp)
def print_emps(self):
for emp in self.employees:
print('=emp=', emp.fullname())
dev_1 = Developer('Alex', 'Brown', 50000, 'Python')
dev_2 = Developer('Lisa', 'Miller', 60000, 'JavaScript')
print(type(dev_1)) # <class '__main__.Developer'>
# print(help(Developer)) # Shows info on Developer class
print(dev_1.fullname()) # Alex Brown
print(dev_2.fullname()) # Lisa Miller
print(dev_1.prog_lang) # Python
print(dev_2.prog_lang) # JavaScript
print(dev_1.pay) # 50000
dev_1.apply_raise()
print(dev_1.pay) # 55000
mgr_1 = Manager('Jack', 'Russell', 70000)
mgr_1.add_emp(dev_1)
mgr_1.print_emps() # Alex Brown
mgr_1.add_emp(dev_2)
mgr_1.print_emps() # Alex Brown, Lisa Miller
print(isinstance(mgr_1, Manager)) # True
print(isinstance(mgr_1, Employee)) # True
print(isinstance(dev_1, Manager)) # False
print(issubclass(Manager, Employee)) # True
print(issubclass(Manager, Developer)) # False
Python OOP Special (Magic/Dunder) Methods
More info on Special (Magic/Dunder) Methods
class Employee:
raise_amount = 1.04
num_of_emps = 0
def __init__(self, first, last, pay):
self.first = first
self.last = last
self.email = first + '.' + last + '@email.com'
self.pay = pay
Employee.num_of_emps += 1
def fullname(self):
return '{} {}'.format(self.first, self.last)
def apply_raise(self):
self.pay = int(self.pay * self.raise_amount)
# This method is used for debug. It makes print(cls) and repr(cls) look pretty
def __repr__(self):
return "Employee('{}', '{}', {})".format(self.first, self.last, self.pay)
# This method is used for debug. It makes print(cls) and str(cls) look pretty
def __str__(self):
return '{} - {}'.format(self.fullname(), self.email)
def __len__(self):
return len(self.fullname())
emp_1 = Employee('Alex', 'Brown', 50000)
emp_2 = Employee('Lisa', 'Miller', 60000)
print(emp_1) # Alex Brown - Alex.Brown@email.com
print(repr(emp_1)) # Employee('Alex', 'Brown', 50000)
print(emp_1.__repr__()) # same as prev line
print(str(emp_1)) # Alex Brown - Alex.Brown@email.com
print(emp_1.__str__()) # same as prev line
print(len(emp_1)) # 10
Python OOP Property Decorators - Getters, Setters, and Deleters
class Employee:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def email(self):
return '{}.{}@email.com'.format(self.first, self.last)
@property
def fullname(self):
return '{} {}'.format(self.first, self.last)
@fullname.setter
def fullname(self, name):
self.first, self.last = name.split(' ')
@fullname.deleter
def fullname(self):
print('Deleted!')
self.first = None
self.last = None
emp_1 = Employee('Alex', 'Brown')
emp_2 = Employee('Lisa', 'Miller')
emp_1.first = 'Jim'
print(emp_1.fullname) # Jim Brown
print(emp_1.email) # Jim.Brown@email.com
emp_1.fullname = 'Jack Russell'
print(emp_1.first) # Jack
print(emp_1.fullname) # Jack Russell
print(emp_1.email) # Jack.Russell@email.com
del emp_1.fullname
print(emp_1.first) # None
print(emp_1.fullname) # None None
Source: CoreyMS.com