Python Arena
Step 1 of 4

Class variables

So far every object has had its own values for its attributes: two products, two prices. Sometimes a value belongs to the class as a whole and is shared by all its objects, such as a tax rate that's the same for every product. That's a class variable. You write it inside the class but outside any method, without self.:

class Product:
    tax_percent = 24

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

    def total_price(self):
        return self.price + self.price * Product.tax_percent / 100


print("Tax:", Product.tax_percent, "%")
bread = Product("Bread", 4)
lamp = Product("Lamp", 50)
print(bread.total_price(), lamp.total_price())

Product.tax_percent = 10
print(bread.total_price(), lamp.total_price())
Output
Tax: 24 %
4.96 62.0
4.4 55.0

You reach a class variable through the class's name: Product.tax_percent. It exists as soon as the class does, before any object is created, which is why the first print works. There is only one tax_percent, so changing it once changes the total price of every product.

Attributes that each object has for itself, like self.price, are called instance variables (an object is an instance of its class). Any value can be a class variable, a list or a dictionary too.

Counting objects

A class variable can count how many objects have been created, and give each new object the next number:

class Ticket:
    sold = 0

    def __init__(self, show):
        Ticket.sold += 1
        self.number = Ticket.sold
        self.show = show

    def __str__(self):
        return f"Ticket {self.number}: {self.show}"


a = Ticket("Hamlet")
b = Ticket("Hamlet")
c = Ticket("Cats")
print(a)
print(c)
print("Tickets sold:", Ticket.sold)
Output
Ticket 1: Hamlet
Ticket 3: Cats
Tickets sold: 3

Ticket.sold is shared, and self.number is each ticket's own copy of what it was at that moment.

Change it through the class

Inside a method, self.sold can read the class variable: when an object has no attribute of that name, Python looks in its class. But assigning to self.sold creates a new attribute in that one object, and the class variable doesn't change:

class Ticket:
    sold = 0

    def __init__(self):
        self.sold += 1


a = Ticket()
b = Ticket()
print(Ticket.sold, a.sold, b.sold)
Output
0 1 1

Each ticket now has its own sold, and the shared count is still 0. To change a class variable, always go through the class's name: Ticket.sold += 1.

Your task

Challenge 1 of 3

Every new club member should get the next member number. Fill in the blanks so the program prints:

1 Ada
2 Linus
3 Grace
Members: 3

Challenge 2

What does this program print? Type each line it prints.

Challenge 3

Write the class Coin. It has two class variables:

  • values, a dictionary of the value in cents of each kind of coin: "penny" is 1, "nickel" is 5, "dime" is 10 and "quarter" is 25;
  • minted, the number of coins created so far, at first 0.

The constructor takes the kind of coin (one of the keys of values), stores it in the attribute kind, and adds one to minted. The method cents(self) returns the coin's value from the dictionary.

For example, this code:

print(Coin.values["dime"])
purse = [Coin("quarter"), Coin("penny"), Coin("dime")]
total = 0
for coin in purse:
    total += coin.cents()
print(total)
print(Coin.minted)

prints:

10
36
3