Python Classes, Formatted Strings, Errors and Variable Scope

Juma Shafara - Jul 23 - - Dev Community

In this notebook, we will explore some fundamental concepts in Python that are essential for writing clean, efficient, and maintainable code. These concepts include:

  • Classes and Objects
  • Formatted Strings
  • Handling Errors
  • Variable Scopes

Don't Miss Any Updates!

Before we continue, we have a humble request, to be among the first to hear about future updates of the course materials, simply enter your email below, follow us on (formally Twitter), or subscribe to our YouTube channel.

Classes and Objects

In Python, everything is an object. A class helps us create objects.

Creating a Class

Use the class keyword to create a class

Here is the syntax:

class className:
    statement(s)
Enter fullscreen mode Exit fullscreen mode

Below is an example:

class Person:
    first_name = "Betty"
    last_name = "Kawala"
    age = 30
Enter fullscreen mode Exit fullscreen mode

Instantiating a class

Now we can ceate an object from the class by instantiating it.

To instantiate a class, add round brackets to the class name.

person_obj1 = Person()

type(person_obj1)
Enter fullscreen mode Exit fullscreen mode
__main__.Person
Enter fullscreen mode Exit fullscreen mode

After instantiating a class, we can now access the object's properties.

# print attributes
print(person_obj1.first_name)
print(person_obj1.last_name)
print(person_obj1.age)
Enter fullscreen mode Exit fullscreen mode
Betty
Kawala
30
Enter fullscreen mode Exit fullscreen mode

Class Attributes

A class can have attributes. Forexample the Person Class can have attributes like the name, height and feet

class Person:
    def __init__(self, name, height, feet):
        self.name = name
        self.height = height
        self.feet = feet
Enter fullscreen mode Exit fullscreen mode

Note!

For now, focus on the syntax. Later we will explain the init() function and the self parameter.

Now that our class is ready, we can now instantiate it and provide values to it's attributes.

This process can also be called "creating an instance of a class".

An instance is simply the object created from a class

In this example, person_obj1 is a unique instance of the person class.

# create a class instance
person_obj = Person(
    name='Betty Kawala', 
    height=1.57, 
    feet=4
    )
Enter fullscreen mode Exit fullscreen mode

After that, we can now access the properties of the instance (object)

# accessing the properties
print('Name:', person_obj.name)
print('Height:', person_obj.height)
print('Feet:', person_obj.feet)
Enter fullscreen mode Exit fullscreen mode
Name: Betty Kawala
Height: 1.57
Feet: 4
Enter fullscreen mode Exit fullscreen mode

The self parameter allows us to access the attributes and methods of a class

The __init__() function allows us to provide values for the attributes of a class

Instances are unique

Let's say you have 500 people and you need to manage their data.

It is inefficient to create a variable for each of them, instead, you can create unique instances of a class.

In this example, the student1 and student2 instances are different from each other

class Student:
  def __init__(self, id_number, name, age):
    self.id_number = id_number
    self.name = name
    self.age = age

student1 = Student(5243, "Mary Doe", 18)
student2 = Student(3221, "John Doe", 18)

print("Student 1 ID:", student1.id_number)
print("Student 1 Name:", student1.name)
print("Student 1 Age:", student1.age)

print("---------------------")

print("Student 2 ID:", student2.id_number)
print("Student 2 Name:", student2.name)
print("Student 2 Age:", student2.age)
Enter fullscreen mode Exit fullscreen mode
Student 1 ID: 5243
Student 1 Name: Mary Doe
Student 1 Age: 18
---------------------
Student 2 ID: 3221
Student 2 Name: John Doe
Student 2 Age: 18
Enter fullscreen mode Exit fullscreen mode

Methods

Methods are functions that can access the class attributes.

These methods should be defined (created) inside the class

class Person:
    def __init__(self, name, height, feet):
        self.name = name
        self.height = height
        self.feet = feet

    def jump(self):
        return "I'm jumping " + str(self.feet) + " Feet"
Enter fullscreen mode Exit fullscreen mode
person_obj1 = Person(name='Juma', height=1.59, feet=5)

print(person_obj1.jump())
Enter fullscreen mode Exit fullscreen mode
I'm jumping 5 Feet
Enter fullscreen mode Exit fullscreen mode

As you may notice, we used the self parameter to access the feet attribute

You can also pass an argument to a method.

class Student:
    def __init__(self, id_number, name, age):
        self.id_number = id_number
        self.name = name
        self.age = age

    def greet_student(self, greetings):
        print("Hello" + self.name + ", " + greetings)

student1 = Student(43221, "Agaba Calvin", 18)

# the string below will be passed as 
# the value of the greetings parameter
student1.greet_student("Welcome to this Python Tutorial!")
Enter fullscreen mode Exit fullscreen mode
HelloAgaba Calvin, Welcome to this Python Tutorial!
Enter fullscreen mode Exit fullscreen mode

Python Inheritance

Inheritance is a feature that allows us to create a class that inherits the attributes or properties and methods of another class

Example

The Animal class below can be used to tell that an animal can eat

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def eat(self):
        print(f"{self.name} is eating.")
Enter fullscreen mode Exit fullscreen mode

Let's say we need to create another class called Dog.

Since a dog is also an animal, it's more efficient to have access to all the properties and methods of the Animal class than to create another

This example creates a class named Dog and inherits from the Animal class

class Dog(Animal):
    def __init__(self, name, age, color):
        super().__init__(name, age)
        self.color = color

    def sound(self):
        print(self.name, "barks")
Enter fullscreen mode Exit fullscreen mode

Note!

As you may notice, to inherit from a parent, we simply pass the name of that class as a parameter of the child class.

Now we can use the properties and methods of both the Animal and the Dog classes using just one instance

dog1 = Dog(name='Brian', age=8, color='White')
dog1.eat()
dog1.sound()
Enter fullscreen mode Exit fullscreen mode
Brian is eating.
Brian barks
Enter fullscreen mode Exit fullscreen mode

The super() and __init__ functions found in the Dog class allow us to inherit the properties and methods of the Animal class.

Parent and Child Class

The parent class is the class from whick the other class inherits from.

The child class is the the class that inherits from another class

In our example above, the Animal is the parent class while the Dog class is the child class

Formatted Strings

In Python, we can format a string by adding substring/s within it.

The format() function allows us to format strings.

Placeholders {}

Placeholders help us control which part of the string should be formated.

They are defined using curly braces {}.

In this example, we will concatenate (add) a substring to where the curly braces are placed

text = "I love {} very much!"
formatted_text = text.format("Python")

print(formatted_text)
Enter fullscreen mode Exit fullscreen mode
I love Python very much!
Enter fullscreen mode Exit fullscreen mode

Multiple placeholders

If you want to format multiple parts of a string, use multiple placeholders.

text = '{} loves to code in {}'
formatted_text = text.format('Juma', 'JavaScript')

print(formatted_text)
Enter fullscreen mode Exit fullscreen mode
Juma loves to code in JavaScript
Enter fullscreen mode Exit fullscreen mode

Using Indexes

We can use index numbers to specify exactly where the values should be placed.

The index numbers should be inside the curly braces: {index_numbers}

text = 'I love {2}, {1} and {0} very much!'
formatted_text = text.format('Python', 'JavaScript', 'HTML')

print(formatted_text)
Enter fullscreen mode Exit fullscreen mode
I love HTML, JavaScript and Python very much!
Enter fullscreen mode Exit fullscreen mode

Note!

0 represents the first value, 1 represents the second value and so on.

Using Named Indexes

We can also use named indexes to specify exactly where the values should be placed.

The arguments of the format() function should be in key/value pairs ie key=value.

The key/value pairs should be separated by commas.

text = 'The color of the {fruit} is {color}.'
formatted_text = text.format(fruit='banana', color='yellow')

print(formatted_text)
Enter fullscreen mode Exit fullscreen mode
The color of the banana is yellow.
Enter fullscreen mode Exit fullscreen mode

Literal String Interpolation

Literal string interpolation allows you to use expression inside your strings.

Simply add f before you opening quote, then surround your expressions with curly braces {}.

name = 'Juma'; 
language = 'JavaScript'

statement = f'{name} loves to code in {language}'

print(statement)
Enter fullscreen mode Exit fullscreen mode
Juma loves to code in JavaScript
Enter fullscreen mode Exit fullscreen mode

Here's another example

number1 = 5
number2 = 7
answer = f'The summation of 5 and 7 is {number1 + number2}'

print(answer)
Enter fullscreen mode Exit fullscreen mode
The summation of 5 and 7 is 12
Enter fullscreen mode Exit fullscreen mode

Errors in Python

When coding in Python, you will encounter errors.

When errors occur, the program crashes or stops executing.

Fortunately, errors can be handled in Python

The try...except statment

The try...except statement is used to handle exceptions(errors)

The try statement takes a block of code to test for errors

The except statement handles the exceptions.

try:
    # age = input('Enter your age: ')
    age = '32'

    if age >= 18:
        print('Your vote has been cast')
    else:
        print('You are not eligible to vote')
except:
    print('A problem occured while picking your age \n'
          'You did not enter a number')

text = "\nHello world!"
print(text)
Enter fullscreen mode Exit fullscreen mode
A problem occured while picking your age 
You did not enter a number

Hello world!
Enter fullscreen mode Exit fullscreen mode

Note!

Even when the exception was thrown, the codes after the try...except were still executed

The else statement

The else statement is executed if there are no exceptions thrown.

try:
    text = "Hello World!"
    print(text)
except:
    print("An error occurred.")
else:
    print("No exception was thrown!")
Enter fullscreen mode Exit fullscreen mode
Hello World!
No exception was thrown!
Enter fullscreen mode Exit fullscreen mode

The finally statement

The finally statement is executed whether or not an exception is thrown.

try: 
    text = "hello world"
    print(text)
except:
    print("An error occured.")
finally:
    print("Hello, I am still printed.")

print("----------------------")

# an exception will be thrown here
try: 
    print(undefined_variable)
except:
    print("An error occured.")
finally:
    print("Hello, I am still printed.")
Enter fullscreen mode Exit fullscreen mode
hello world
Hello, I am still printed.
----------------------
An error occured.
Hello, I am still printed.
Enter fullscreen mode Exit fullscreen mode

Throw Exceptions

We can intentionally throw and exception to stop the execution of a program.

The raise keyword throws an excrption.

# Creating your own errors
try: 
    age = 14
    if age < 18:
        raise Exception('Not an adult')
except Exception as error:
    print('A problem occurred \n'
          f'Error: {error}')
Enter fullscreen mode Exit fullscreen mode
A problem occurred 
Error: Not an adult
Enter fullscreen mode Exit fullscreen mode

Kinds of Exceptions

In Python, there are different kinds of exceptions and we can handle them individually with the try...except statement.

try:
    # statements
except ExceptionKind:
    #statments
Enter fullscreen mode Exit fullscreen mode

One of the most common kind of exceptions is the NameError. This is thrown when you use a variable that is not defined

try:
    print(rand_var)
except NameError:
    print('You used a variable that is not defined!')
Enter fullscreen mode Exit fullscreen mode
You used a variable that is not defined!
Enter fullscreen mode Exit fullscreen mode

Variable Scope

Python Variable Scopes

The accessibility of variable depends on its scope. In Python, there are two variable scopes:

  • Global Scope
  • Local Scope

Global Scope

A variable that is defined (created) outside a function has a global scope

A global variable can be accessed anywhere in a program

name = 'Viola'
# name can be accessed here
print(name)

def greet():
    # name can be accessed here
    print('Hello ' + name)

greet()
Enter fullscreen mode Exit fullscreen mode
Viola
Hello Viola
Enter fullscreen mode Exit fullscreen mode

Local Scope

A variable that is defined (created) inside a function has a local scope. A local scope variable can only be accessed and used inside the function.

def greet():
    local_name = 'Viola'
    print('Hello ' + local_name)

greet()

try:
    # local_name cannot be accessed here
    print(local_name)
except Exception as e:
    print(e)
Enter fullscreen mode Exit fullscreen mode
Hello Viola
name 'local_name' is not defined
Enter fullscreen mode Exit fullscreen mode

The global Keyword

We can force a local variable to be a global variable by using the global keyword.

# Global Keyword

def add():
    global summ
    number1 = 5
    number2 = 7
    summ = number1 + number2
    return summ

add()

# summ is accessible even outside the function
print(summ)
Enter fullscreen mode Exit fullscreen mode
12
Enter fullscreen mode Exit fullscreen mode

What's on your mind? Put it in the comments!


Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . .