Object Oriented Programming in Python

In normal life to tend to think in sequences of activities.

Procedural programming

  • Code as a sequence of steps
  • Great for data analysis and scripts
Procedures, sequences and routines

Object-oriented programming

  • Code as interactions of objects
  • Great for building framework and tools
  • Maintainable and reusable code!

Objects as datastructures

Object = state + behavior

Encapsulation – bundling data with code operating on it

Classes

A Class can be seen as a blueprint for objects defining states and behaviours.

Objects in Python

  • Everything in Python is an object
  • Every object has a class
  • Use type() to find the class
ObjectClass
5int
“Hello”str
pd.DataFrame()DataFrame
np.meanfunction
Everything in Python is an object
import numpy as np

a = np.array([1, 2, 3, 4,])
print(type(a))
numpy.ndarray

Attributes and methods

State <-> attributes

import numpy as np
a = np.array([1, 2, 3, 4])
# shape attribute
a.shape
(4,)

Behaviour <-> methods

import numpy as np
a = np.array([1, 2, 3, 4])
# reshape method
a.reshape(2,2)
array([[1, 2], 
       [3, 4]])
  • Use obj. to access attributes and methods

Object = attributes + methods

  • attributes <-> variables <-> obj.my_attribute ,
  • method <-> function() <-> obj.my_method() .
import numpy as np
a - np.array([1, 2, 3, 4])
dir(a)                       # <--- list all attributes and methods
['T',
 '__abs__',
 ...
 'trace',
 'transpose',
 'var',
 'view']

A basic class

class Customer:
    # code for class goes here
    pass
  • class <name>: starts a class definition
  • code inside class is indented
  • use pass to create an “empty” class
c1 = Customer()
c2 = Customer()
  • use ClassName() to creatie an object of class Classname

Adding methods to a class

class Customer:
    def identify(self, name):
        print("I am Customer "  name)
  • method definition – function definition within class
  • use self as the 1st argument in method definition
cust = Customer()
cust.identify("Hylke")
I am Customer Hylke
  • ignore self when calling method on an object
class Customer:
    def identify(self, name):
        print("I am Customer " + name)

cust = Customer()
cust.identify("Hylke")

What is self?

  • classes are templates, how to refer data of a particular object?
  • self is a stand-in for a particular object used in class definition
  • should be the first argument of any method
  • Python will take care of self when methods called for an object:
    • cust.identify("Laura") will be interpreted as Customer.identify(just, "Laura")

How to create attributes

  • Encapsulation : bundling data with methods that operate on data
  • Customer ‘s’ name should be an attribute

Attributes are created by assignment (=) in methods

Adding an attribute to a class

class Customer:
    # set the name attribute of an object to new_name
    def set_name(self, new_name):
        # Create an attribute by assigning a value
        self.name = new_name           # <--- will create .name when set_name is called


cust - Customer()                      # <--- .name doesn't exist here yet
cust.set_name("Hylke Rozema")          # <--- .name is created and set to "Hylke Rozema"
print(cust.name)                       # <--- .name can be used
Hylke Rozema

Old version

class Customer:



    # Using a parameter
    def identify(self, name):
       print("I am Customer" + name)

cust = Customer()

cust.identify("Mark Carr")
I am Customer Mark Carr

New version

class Customer:
   def set_name(self, new_name):
       self.name = new_name

   # Using .name from the object it*self*
   def identify(self):
      print("I am Customer" + self.name)

cust = Customer()
cust.set_name("Mary Dillan")
cust.identify()
I am Customer Mary Dillan

The __init__ constructor

  • Methods are function definitions within a class
  • self as the first argument
  • Define attributes by assignment
  • Refer to attributes aan class via self.____
class MyClass:
    # function definition in class
    # first argument is self
    def my_method1(self, other_args...):
        # do things here

    def my_method2(self, my_attr):
        # attribute created by assignment
        self.my_attr = my_attr
        ...

Constructor __init__() method

  • Add data to object when creating it?
  • Constructor __init__() method is called every time an object is created
class Customer:
    def __init__(self, name):
       self.name = name           # <--- Create the .name attribute and set it to name parameter
       print("The __init__ method was called")

cust = Customer("Hylke Rozema")   # <--- __init__ is implicitly called
print(cust.name)
The __init__ method was called
Hylke Rozema
 class Customer:
       def __init__(self, name, balance):  # <-- balance parameter added
        self.name = name
        self.balance = balance             # <-- balance attribute added
        print("The __init__ method was called")
cust = Customer("Hylke Rozema", 1000)      # <-- __init__ is called
print(cust.name)
print(cust.balance)
The __init__ method was called
Hylke Rozema
1000

Write a class from scratch

You are a Python developer writing a visualization package. For any element in a visualization, you want to be able to tell the position of the element, how far it is from other elements, and easily implement horizontal or vertical flip .

The most basic element of any visualization is a single point. In this exercise, you’ll write a class for a point on a plane from scratch.

Instructions

Define the class  Point that has:

  • Two attributes, x and y – the coordinates of the point on the plane;
  • A constructor that accepts two arguments, x and y, that initialize the corresponding attributes. These arguments should have default value of 0.0;
  • A method distance_to_origin() that returns the distance from the point to the origin. The formula for that is x2+y2. 
  • A method reflect(), that reflects the point with respect to the x- or y-axis:
    • accepts one argument axis,
    • if axis="x" , it sets the y (not a typo!) attribute to the negative value of the y attribute,
    • if axis="y", it sets the x attribute to the negative value of the x attribute,
    • for any other value of axis, prints an error message. Reflection of a point with respect to y and x axes

Note: You can choose to use sqrt() function from either the numpy or the mathpackage, but whichever package you choose, don’t forget to import it before starting the class definition!


To check your work, you should be able to run the following code without errors:

pt = Point(x=3.0)
pt.reflect("y")
print((pt.x, pt.y))
pt.y = 4.0
print(pt.distance_to_origin())

and return the output

(-3.0,0.0)
5.0
from numpy import sqrt

# Write the class Point as outlined in the instructions
class Point:
    def __init__(self, x=0.0, y=0.0):
        self.x = x
        self.y = y
    def distance_to_origin(self):
        return sqrt(self.x**2 + self.y**2)
    def reflect(self, axis):
        if axis=="x":
            self.y=-self.y
        elif axis=="y":
            self.x=-self.x
        else:
            print("Error")

pt = Point(x=3.0)
pt.reflect("y")
print((pt.x, pt.y))
pt.y = 4.0
print(pt.distance_to_origin())

Notice how you implemented distance_to_origin() as a method instead of an attribute. Implementing it as an attribute would be less sustainable – you would have to recalculate it every time you change the values of the x and y attributes to make sure the object state stays current.

Add a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.