Class Attributes and Methods

Contents

Class Attributes and Methods#

Attributes#

Python also supports class level attributes, which are attributes shared across all instances. This is useful because it would be wasteful for instances to store shared data inside every instance.

Syntax

Class attributes are defined directly underneath the class name and are indented to the same level as instance methods as shown below:

class ClassName:

    attribute_1 = value_1
    attribute_2 = value_2

    def method1(self, parameter_1, ..., parameter_n):
        # do something
        return # optional

Accessing class attributes is done through the class name i.e.

ClassName.attribute_1

Note

Like instance attributes, class attributes are mutable. So be careful using them as you might accidentally change their value!

Example: Interest Rate

In the example below, all bank accounts use the same interest rate. Therefore it is stored as a class attribute, which is accessible by all instances.

class Account:

    interest_rate = 0.0235  # 2.35% interest rate - Class attribute!

    def __init__(self, bsb_number, account_number, balance, holder_name):
        self.bsb_number = bsb_number
        self.account_number = account_number
        self.balance = balance
        self.holder_name = holder_name

    def get_earned_interest(self):
        return Account.interest_rate * self.balance


batman_account = Account("689716", "62228626", 19.39, "Bruce Wayne")
print("Interest rate: {}".format(batman_account.interest_rate))
print("Earned interest: {}".format(batman_account.get_earned_interest()))

superman_account = Account("789546", "86312655", 8.38, "Clark Kent")
print("Interest rate: {}".format(superman_account.interest_rate))
print("Earned interest: {}".format(superman_account.get_earned_interest()))
Output
Interest rate: 0.0235
Earned interest: 0.455665
Interest rate: 0.0235
Earned interest: 0.19693000000000002

In this example, the interest rate of both Batman’s and Superman’s accounts are the same, 2.35%.

../../_images/instances_account_interest_rates.png

Methods#

Classes can also have associated methods, which are useful for managing class attributes.

Class methods are defined by using the @classmethod decorator immediately before the method and by setting the first parameter to cls, which is a reference to the class rather than the instance.

class ClassName:

    @classmethod
    def class_method1(cls, parameter_1, ..., parameter_n):
        # do something
        return # optional

    def instance_method1(self, parameter_1, ..., parameter_n):
        # do something
        return # optional

Class methods are called by

ClassName.class_method1(argument_1, ..., argument_n)

Example

In the example below, a shared transaction counter is created. This counter is managed through the class method get_new_transaction_number so that each time a bank account records a transaction it is unique across all transactions.

class Account:

    interest_rate = 0.0235
    transaction_number = 0

    @classmethod
    def get_new_transaction_number(cls):
        cls.transaction_number += 1
        return cls.transaction_number

    def __init__(self, bsb_number, account_number, balance, holder_name):
        self.bsb_number = bsb_number
        self.account_number = account_number
        self.balance = balance
        self.holder_name = holder_name

        self.transactions = []

    def deposit(self, amount):
        self.balance += amount
        transaction_number = Account.get_new_transaction_number()
        self.transactions.append([transaction_number, amount])

    def withdraw(self, amount):
        self.balance -= amount
        transaction_number = Account.get_new_transaction_number()
        self.transactions.append([transaction_number, -amount])

        if self.balance < 0:
            print("WARNING: Account is overdrawn!")


batman_account = Account("689716", "62228626", 19.39, "Bruce Wayne")
superman_account = Account("789546", "86312655", 8.38, "Clark Kent")

batman_account.deposit(20)
superman_account.deposit(10)
batman_account.withdraw(5)

print(batman_account.transactions)
Output
[[1, 20], [3, -5]]
../../_images/transactions.png

Note

Note that in the class method get_new_transaction_number we use cls to refer to the class, but when we call this method, e.g. in deposit() we use the class name, i.e. Account.get_new_transaction_number().

Code Challenge: Track the Fleet Size
../../_images/fleet_lasers.png

As your fleet grows its getting harder to track how many ships you’ve made. Use a class attribute called fleet_count to record how many ships have been created.

Requirements

  • A class attribute called fleet_count that stores an int with the number of ships that have been created.

  • When a ship is created the value of fleet_count must be incremented by 1.

Instructions

  1. Copy and paste your solution from General Methods > “ 🔫Lasers” into the scaffold below.

  2. Add a class attribute called fleet_count.

  3. Modify the constructor (__init__) to increment fleet_count.

class Spaceship:

    def __init__(self, name):
        self.name = name

enterprise = Spaceship("Enterprise", 10000)
enterprise = Spaceship("Millennium Falcon", 1000)
enterprise = Spaceship("Serenity", 2000)

print(Spaceship.fleet_count)
Solution

Solution is locked

Code Challenge: Register Ships
../../_images/fleet_stats.png

As you add more and more ships to your fleet, you’ve forgotten the names of all your ships. Add a class method to register ships with their name. This registry must be stored as a list class attribute.

Requirements

  • A class attribute called fleet_names that stores a list containing the names of ships in the fleet as str.

  • A class method called register_ship with:

    • Functionality: Adds the name of the ship to the fleet_names list

    • Parameters:

      • cls

      • ship - the ship to be added

    • Returns: None

  • A class method called fleet_count with:

    • Functionality: Calculates the number of registered ships

    • Parameters:

      • cls

    • Returns: An integer corresponding to the number of registered ships

Instructions

  1. Copy and paste your solution from General Methods > “ 🔫Lasers”.

  2. Add a class attribute called fleet_names.

  3. Add a class method called register per the requirements.

  4. Test your code by registering ships and then printing fleet count e.g.

enterprise = Spaceship("Enterprise", 10000)
Spaceship.register_ship(enterprise)

falcon = Spaceship("Millennium Falcon", 1000)
Spaceship.register_ship(falcon)

print(Spaceship.fleet_count())
Solution

Solution is locked