Your first class
So far you have used classes that come with Python, such as Fraction and date. Now you'll write your own. A class is defined with the keyword class, the class's name and a colon. What belongs to the class is indented under it, as in a function:
class Planet:
pass
This class is empty: pass is the statement that does nothing, there because Python needs at least one line in the block. It already works as a blueprint, though.
Why a capital P? PEP 8 gives the names of new classes a look of their own, so that a reader can tell them apart from everything else. Compare weather_station, a variable or a function, with WeatherStation, a class: no underscores, and a capital letter at the start of every word. This style is called PascalCase. With it, Planet() reads as "make a planet", while planet_count() is a function call. (As you saw in the previous module, Python's built-in classes such as int and list, and some library classes such as date, have names in small letters. Your own classes should still follow the custom.)
Objects and their attributes
To make an object, call the class like a function. Then you can attach attributes to the object, its own variables, by assigning to them with a dot:
class Planet:
pass
home = Planet()
home.name = "Earth"
home.moons = 1
red = Planet()
red.name = "Mars"
red.moons = 2
print(home.name, home.moons)
print(red.name, red.moons)
Earth 1
Mars 2Each object has its own attributes: home.name and red.name are two different variables, one in each object. (As in the code above, PEP 8 asks for two blank lines around a class, as around a function.)
Always through the object
An attribute is stored inside its object, and the way to it goes through the object: the object's name, a dot, then the attribute's name. Leave out the object, and Python looks for an ordinary variable of that name instead:
class Planet:
pass
home = Planet()
home.moons = 1
print(home.moons)
print(moons)
1Traceback (most recent call last):
File "main.py", line 8, in <module>
print(moons)
^^^^^
NameError: name 'moons' is not definedThe program has no variable moons, only an object home with an attribute of that name. And since every Planet object can have moons of its own, a plain moons couldn't say whose moons you mean anyway.
The opposite mistake is asking an object for an attribute it doesn't have: one with a typo in its name, or one the program never gave to that object. Then you get the AttributeError you met in the previous module. Nothing in an empty class makes sure that every planet gets the same attributes. The next step shows how a class can take care of that itself.