Python in Detail: Class Attributes
Welcome to the Class Attributes lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
We've seen attributes on instances, but classes can also have attributes.
>
class Cat:favorite_food = "salmon"def __init__(self, name):self.name = name- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
Cat.favorite_foodResult:
'salmon'
Class attributes are accessible via
Cat.favorite_food, but they're also accessible viasome_cat.favorite_food. When we access an attribute, Python checks for an instance attribute first, and only then checks for a class attribute.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
keanu = Cat("Keanu")keanu.favorite_foodResult:
'salmon'
If we change the class attribute's value, the change shows up on all of the instances.
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
keanu = Cat("Keanu")Cat.favorite_food = 'chicken'keanu.favorite_foodResult:
'chicken'
If we define
Cat.favorite_foodbut also definekeanu.favorite_food, those are separate attributes. The instancekeanuhas an attribute, and the class has an attribute with the same name. Python checks for instance attributes before checking for class attributes, so the instance attribute "wins".In the next example, Keanu's favorite food is tuna. But all other instances of
Catstill like salmon.>
class Cat:favorite_food = "salmon"def __init__(self, name):self.name = namekeanu = Cat("Keanu")keanu.favorite_food = "tuna"- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
keanu.favorite_foodResult:
'tuna'
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
Cat.favorite_foodResult:
'salmon'
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
ms_fluff = Cat("Ms. Fluff")ms_fluff.favorite_foodResult:
'salmon'
We can define and manipulate class attributes like this because Python classes themselves are objects! Keanu is an instance of
Cat:>
class Cat:def __init__(self, name):self.name = namekeanu = Cat("Keanu")- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
isinstance(keanu, Cat)Result:
True
But the
Catclass is an instance ofobject, like all classes are:- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
isinstance(Cat, object)Result:
True
When we assign class attributes, we're setting an attribute on an object. In this case, the object just happens to be a class.
All objects are instances of some class. And we just saw that classes are objects. So are classes themselves instances of some class? Yes, but that's a topic for another lesson!
The next code problem requires a new function,
assert_raises, which we'll use in several places throughout this course. This function is specific to Execute Program, and isn't a part of Python itself. It takes two arguments: an expected exception type and a function.assert_raisescalls the function. If the function raises the expected exception, nothing happens. But if the function doesn't raise the expected exception, thenassert_raisesraises its own exception. The code example below usesassert_raisesto check that your code raises aValueError.Here's a code problem:
We want to make sure that all cats have unique names. To solve that, we can track all existing cats in a class attribute on the
Catclass. When instantiating a new cat, raise aValueErrorif another cat already has that name.class Cat:# Our solution stores the cat objects in this list. It's also OK to store# only the names in the list.population = []def __init__(self, name):self.name = namefor existing_cat in Cat.population:if existing_cat.name == self.name:raise ValueError("Name conflict")Cat.population.append(self)ms_fluff = Cat("Ms. Fluff")assert_raises(ValueError, lambda: Cat("Ms. Fluff"))keanu = Cat("Keanu")assert_raises(ValueError, lambda: Cat("Keanu"))- Goal:
None
- Yours:
None