# Python classes#

If you’ve not used Python classes before, this guide will give you an introduction to what they are and what they are used for.

In general, a `class`

is a set of instructions for how to create an object. An instance of a class is the object that is created from the class.
As an example, we can create a class that defines a fraction.

```
from math import gcd
class Fraction:
"""A fraction."""
def __init__(self, numerator, denominator):
self.numerator = numerator
self.denominator = denominator
def print_numerator(self):
print(self.numerator)
def __str__(self):
"""Get string representation."""
return str(self.numerator) + " over " + str(self.denominator)
def __add__(self, other):
"""Add two fractions."""
assert isinstance(other, Fraction)
new_numerator = self.numerator * other.denominator + other.numerator * self.denominator
new_denominator = self.denominator * other.denominator
common_factor = gcd(new_numerator, new_denominator)
return Fraction(new_numerator // common_factor, new_denominator // common_factor)
def __mul__(self, other):
"""Multiply two fractions."""
assert isinstance(other, Fraction)
new_numerator = self.numerator * other.numerator
new_denominator = self.denominator * other.denominator
common_factor = gcd(new_numerator, new_denominator)
return Fraction(new_numerator // common_factor, new_denominator // common_factor)
```

This class contains a number of functions: functions inside a class are called methods.
Each method starts with the `self`

input: this refers to the instance of the class itself and can be used to store information
that other methods will need. (You could use another name instead of `self`

but it’s very very common practice to use `self`

.)
Function that start and end with a double underscore (`__`

) are special methods.

The special method `__init__`

is run when an instance of the class is created. In this function, we store the numerator and denominator of the
fraction as `self.numerator`

and `self.denominator`

.

We can create a fraction and call the `print_numerator`

method like this:

```
half = Fraction(1, 2)
half.print_numerator()
```

This first line will run `__init__`

with `half`

as `self`

, `1`

as `numerator`

and `2`

as `denominator`

. The second line will run `print_numerator`

with `half`

as `self`

, and will therefore
print `1`

.

The special method `__str__`

defines what happens when you `print`

an instance of your class. In our example, `print(half)`

will print `1 over 2`

.

The special method `__add__`

defines what the `+`

operator does. If you read the implementation above, you can see that `__add__`

is adding fractions in the way you would expect. For example, you can add two fractions like this:

```
half = Fraction(1, 2)
third = Fraction(1, 3)
print(half + third)
```

The special method `__mul__`

defines what the `*`

operator does. For example, you can multiply two fractions like this:

```
half = Fraction(1, 2)
third = Fraction(1, 3)
print(half * third)
```

There are a lot more special methods that you can use, including those to define the behaviour of `-`

, `/`

, `//`

, `**`

, `@`

, `[]`

, `=`

, `<`

, `<=`

, `>`

, and `>=`

. You can find
(details of these in the Python documentation](https://docs.python.org/3/reference/datamodel.html#specialnames)