Objects & Classes

Python is an object-oriented programming (OOP) language that uses a paradigm centered around objects and classes.

library(reticulate)
py_install("matplotlib")
Using virtual environment "~/.virtualenvs/r-reticulate" ...
#py_install("pandas")
#py_install("numpy")
#use_virtualenv("r-reticulate")
#plt <- import("matplotlib.pyplot")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

Classes


A class is a blueprint or template for creating objects. It defines the structure and behavior that its objects will have.

  • Think of a class as a cookie cutter and objects as the cookies cut from that template.

Creating classes

  • In Python, you can create classes using the class keyword.
  • Here below nameofclass is the class we are declaring/creating
class nameofclass:

Attributes

  • Syntax: class_attribute = value
  • Class attributes are variables shared among all class instances (objects).
  • They are defined within the class but outside of any methods.
class nameofclass:
        # Attributes are shared by all instances (objects)
        class_attribute = value

Accessing Attributes

  • Access a class attribute shared by all class instances.
  • class_attr_value = ClassName.class_attribute accesses the class attribute class_attribute from the ClassName class and assigns its value to the variable.
    class_attr_value.
# Accessing class attributes (shared by all instances)
class_attr_value = ClassName.class_attribute

Methods

When you create a class, you specify the attributes(data) and methods (functions) that objects of that class will have.

  • Attributes are defined as variables within the class, and
  • methods are defined as functions.
  • For example,you can design
    • a “Car” class with
    • attributes such as “color” and “speed,” along with
    • methods like “accelerate.”
class nameofclass:
        # Attributes are shared by all instances (objects)
        class_attribute = value
        
        # Instance methods (functions)
        def method1(self, parameter1, parameter2,...):
                # Method code
                pass

Constructor Method

  • Syntax: def __init __(self, attribute1, attribute2, …):
  • The __init__ method is a special method known as the constructor.
  • It initializes the instance attributes (also called instance variables) when an object is created. It tell python you are making a new class
  • The self parameter is the first parameter of the constructor, referring to the instance being created: the newly created instance of the class
  • attribute1, attribute2, and so on are parameters passed to the constructor when creating an object, they are used to initialize the class
  • Inside the constructor, self.attribute1, self.attribute2, and so on are used to assign values to instance attributes.
class nameofclass:
        # Attributes are shared by all instances (objects)
        class_attribute = value
        
        
        # Constructor method (initialize instance attributes)
        def __init__(self, attribute1, attribute2, ...):
                self.attribute1 = attribute1
                self.attribute2 = attribute2
                # ... 
        
        # Instance methods (functions)
        def method1(self, parameter1, parameter2, ...):
                # Method logic
                pass
    
        def method2(self, parameter1, parameter2, ...):
                # Method logic
                pass        

Instance Attributes

  • Instance attributes are variables that store data specific to each class instance.
  • They are initialized within the __init__ method using the self keyword followed by the attribute name.
  • These attributes hold unique data for each object created from the class.

Instance Methods

  • Instance methods are functions defined within the class.
  • They operate on the instance’s data (instance attributes) and can perform actions specific to instances.
  • The self parameter is required in instance methods, allowing them to access instance attributes and call other methods within the class.

Objects


An object is a fundamental unit in Python that represents a real-world entity or concept. Objects can be tangible (like a car) or abstract (like a student’s grade).

Every object has two main characteristics:

State

The attributes or data that describe the object.

  • For your “Car” object, this might include attributes like “color”, “speed”, and “fuel level”.

Behavior

The actions or methods that the object can perform.

  • In Python, methods are functions that belong to objects and can change the object’s state or perform specific operations.

Creating Objects (Instantiating)

  • Once you’ve defined a class, you can create individual objects (instances) based on that class.

  • Each object is independent and has its own set of attributes and methods.

  • To create objects (instances) of the class, you call the class like a function and provide arguments the constructor requires.

  • Each object is a distinct instance of the class, with its own instance attributes and the ability to call methods defined in the class.

  • so: “my_car = Car()” as a full example look below:

    # Create objects (instances) of the class
    object1 = nameofclass(arg1, arg2, ...)
    object2 = nameofclass(arg1, arg2, ...)

Calling Method on Objects

  • You interact with objects by calling their methods or accessing their attributes using dot notation.
  • For example, if you have a Car object named my_car, you can set its color with my_car.color = “blue” and accelerate it with my_car.accelerate() if there’s an accelerate method defined in the class.
  • So let’s call methods on objects: object1 & object2
  • The methods method1 and method2 were defined in nameofclass class
  • We will pass parameters param1_value and param2_value as arguments to these methods

Dot Notation

# Calling methods on objects
# Method 1: Using dot notation
result1 = object1.method1(param1_value, param2_value, ...)
result2 = object2.method2(param1_value, param2_value, ...)

By Assignment

  • Here’s an alternative way to call an object’s method by assigning the method reference to a variable.
  • method_reference = object1.method1 assigns the method method1 of object1 to the variable method_reference.
  • Later, call the method using the variable like this: result3 = method_reference(param1_value, param2_value, …).
  • This is kinda of a long way around it, but it’s there
# Method 2: Assigning object methods to variables
method_reference = object1.method1  # Assign the method to a variable
result3 = method_reference(param1_value, param2_value, ...)

Accessing Attributes

  • Here, you are accessing an object’s attribute using dot notation.
  • attribute_value = object1.attribute1 retrieves the value of the attribute attribute1 from object1 and assigns it to the variable attribute_value.
# Accessing object attributes
attribute_value = object1.attribute1  # Access the attribute using dot notation

Modify Attributes

  • You will modify an object’s attribute using dot notation.
  • object1.attribute2 = new_value sets the attribute attribute2 of object1 to the new value new_value.
# Modifying object attributes
object1.attribute2 = new_value  # Change the value of an attribute using dot notation

Example: Car


  • Let’s create a car class
  • car instances
  • accelerate them
  • display their current speeds

Define Class & Methods

Steps

Let’s start by defining a Car class that includes the following attributes and methods:

  • Class attribute max_speed, which is set to 120 km/h.
  • Constructor method __init__ that takes parameters for the car’s make, model, color, and an optional speed (defaulting to 0). This method initializes instance attributes for make, model, color, and speed.
  • Method accelerate(self, acceleration) that allows the car to accelerate. If the acceleration does not exceed the max_speed, update the car’s speed attribute. Otherwise, set the speed to the max_speed.
  • Method get_speed(self) that returns the current speed of the car.
class Car:
    # Class attribute (shared by all instances)
    max_speed = 120  # Maximum speed in km/h
    
    # Constructor method (initialize instance attributes)
    def __init__(self, make, model, color, speed=0):
        self.make = make
        self.model = model
        self.color = color
        self.speed = speed  # Initial speed is set to 0
        
    # Method for accelerating the car
    def accelerate(self, acceleration):
        if self.speed + acceleration <= Car.max_speed:
            self.speed += acceleration
        else:
            self.speed = Car.max_speed
            
    # Method to get the current speed of the car
    def get_speed(self):
        return self.speed

Create Objects

Now, we will instantiate two objects of the Car class, each with the following characteristics:

  • car1: Make = “Toyota”, Model = “Camry”, Color = “Blue”
  • car2: Make = “Honda”, Model = “Civic”, Color = “Red”
  • when we create an object, we call the code like a function: the arguments passed to the Car constructor are used to initialize the data attributes of the newly created Car instance
  • It is helpful to think of self, as a box that contains all the data attributes of the object
# Create objects (instances) of the Car class
car1 = Car("Toyota", "Camry", "Blue")
car2 = Car("Honda", "Civic", "Red")

Call Methods

Call accelerate Method

Using the accelerate method, increase the speed of car1 by 30 km/h and car2 by 20 km/h

# Accelerate the cars
car1.accelerate(30)
car2.accelerate(20)

Call get_speed Method

Display the current speed of each car using the get_speed method

# Print the current speeds of the cars
print(f"{car1.make} {car1.model} color: {car1.color} is currently at {car1.get_speed()} km/h.")
Toyota Camry color: Blue is currently at 30 km/h.
print(f"{car2.make} {car2.model} color: {car2.color} is currently at {car2.get_speed()} km/h.")
Honda Civic color: Red is currently at 20 km/h.

Note:

  • if we wanted to access the data attribute of an object we just use the . to access whichever one we want: car1.make or car2.model
  • Just like a function we can access each attribute and change it: car1.make = "Buick" will change car1.make value

Call Attributes

  • Of course aside from calling get_speed method we can acquire the speed by calling the .speed to retrieve the speed attribute
car2.speed
20

Example: Circle


We will create two classes: Circle and Rectangle

Create Class

Create Constructor Method

  • The next step is a special method called a constructor __init__, which is used to initialize the object.
  • The inputs are data attributes.
  • The term self contains all the attributes in the set. For example the self.color gives the value of the attribute color and self.radius will give you the radius of the object.
  • We also have the method add_radius() with the parameter r, the method adds the value of r to the attribute radius.
  • To access the radius we use the syntax self.radius
# Create a class Circle

class Circle(object):
    
    # Constructor
    def __init__(self, radius=3, color='blue'):
        self.radius = radius
        self.color = color 
    
    # Method
    def add_radius(self, r):
        self.radius = self.radius + r
        return(self.radius)
    
    # Method
    def drawCircle(self):
        plt.gca().add_patch(plt.Circle((0, 0), radius=self.radius, fc=self.color))
        plt.axis('scaled')
        plt.show()  

Create Object

  • Create an object RedCircle of type Circle

Call Class

  • By creating an object we call Circle class and pass it two parameters: radius and color
# Create an object RedCircle

RedCircle = Circle(10, 'red')

dir

  • If you want to look at the list of all the method’s available for this object use dir()
# Find out the methods can be used on the object RedCircle
dir(RedCircle)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'add_radius', 'color', 'drawCircle', 'radius']

Inspect Attributes

# Print the object attribute radius
RedCircle.radius
10
# Print the object attribute color
RedCircle.color
'red'

Edit Attributes

# Change the object attribute radius to 1

RedCircle.radius = 1
RedCircle.radius
1

Call Method

# Call the method drawCircle
RedCircle.drawCircle()

  • Above you saw how we manually changed the radius, but since we already have a method add_radius we can call it to change the radius
# Use method to change the object attribute radius
print('Radius of object:',RedCircle.radius)
Radius of object: 1
RedCircle.add_radius(2)
3
print('Radius of object of after applying the method add_radius(2):',RedCircle.radius)
Radius of object of after applying the method add_radius(2): 3
RedCircle.add_radius(5)
8
print('Radius of object of after applying the method add_radius(5):',RedCircle.radius)
Radius of object of after applying the method add_radius(5): 8

Create Class

  • Let’s create a class rectangle with the attributes of height, width, and color.
  • Create a method to draw the rectangle
# Create a new Rectangle class for creating a rectangle object

class Rectangle(object):
    
    # Constructor
    def __init__(self, width=2, height=3, color='r'):
        self.height = height 
        self.width = width
        self.color = color
    
    # Method
    def drawRectangle(self):
        plt.gca().add_patch(plt.Rectangle((0, 0), self.width, self.height ,fc=self.color))
        plt.axis('scaled')
        plt.show()

Create Object

# Create a new object rectangle
SkinnyBlueRectangle = Rectangle(2, 3, 'blue')

Call Class

# Print the object attribute height
SkinnyBlueRectangle.height 
3
# Print the object attribute width
SkinnyBlueRectangle.width
2

Call Method

# Use the drawRectangle method to draw the shape
SkinnyBlueRectangle.drawRectangle()

Create Another Object

# Create a new object rectangle
FatYellowRectangle = Rectangle(20, 5, 'yellow')
# Print the object attribute height
FatYellowRectangle.height
5
# Print the object attribute width
FatYellowRectangle.width
20

Call Method

# Use the drawRectangle method to draw the shape
FatYellowRectangle.drawRectangle()


class Circle(object):
    # Constructor
    def __init__(self, radius=3, color='blue'):
        self.radius = radius
        self.color = color
        
    # Method
    def add_radius(self, r):
        self.radius = self.radius + r
        return self.radius
CircleObject = Circle()
CircleObject.radius = 10
CircleObject.radius
10
CircleObject.color
'blue'
class Vehicle:
    color = "white"

    def __init__(self, max_speed, mileage):
        self.max_speed = max_speed
        self.mileage = mileage
        self.seating_capacity = None

    def assign_seating_capacity(self, seating_capacity):
        self.seating_capacity = seating_capacity


V1 = Vehicle(150, 25)
V1.color
'white'
class Graph():
    def __init__(self, id):
        self.id = id
        self.id = 80


val = Graph(200)
print(val.id)
80