Attributes
An empty Dog class makes every dog identical. To tell dogs apart you need data attached to each one. In Python, data attached to an object is called an attribute. Other languages call the same thing a field or a property.
Setting attributes
Python is dynamic, so you do not declare attributes in advance. You assign to them with the dot operator, and the assignment creates the attribute:
class Dog:
pass
dog = Dog()
dog.name = "Rex"
dog.age = 4
Before those two assignments, dog has no name and no age. The class body contains only pass, so nothing exists until the assignments run. Afterwards the object has both.
Reading attributes
You read an attribute with the same dot syntax:
print(dog.name)
print(dog.age)
Rex
4
Reading an attribute that was never set is an error:
print(dog.color)
AttributeError: 'Dog' object has no attribute 'color'
If you are unsure whether an attribute exists, hasattr(dog, "color") returns True or False, and getattr(dog, "color", "unknown") returns a default instead of raising.
Each object has its own attributes
Attributes belong to the object, not to the class. Two dogs can carry different values without affecting each other:
rex = Dog()
luna = Dog()
rex.name = "Rex"
luna.name = "Luna"
print(rex.name, luna.name)
Rex Luna
Python keeps an object's attributes in a dictionary, which vars(rex) shows. For the dog above it would be {'name': 'Rex'}. That dictionary is why attributes can be added at any time, and also why the next gotcha exists.
Changing attributes
Assigning to an attribute that already exists replaces its value. After dog.age = 5, the dog is five, and the old value is gone. You can also compute the new value from the old one, as in dog.age = dog.age + 1, which is how a program would record a birthday.
The lesson's exercise
The starter code defines Dog, creates dog = Dog() and ends with a print that reads dog.name and dog.age. The gap in the middle is yours to fill:
- Set the name. Write
dog.name = "Rex"below the line that creates the dog. - Set the age. Write
dog.age = 4on the next line. The number needs no quotes.
The assignments must come before the print. If they came after it, the print would raise an AttributeError, because the attributes would not exist yet. The complete program:
class Dog:
pass
dog = Dog()
dog.name = "Rex"
dog.age = 4
print(dog.name + " is " + str(dog.age) + " years old")
Rex is 4 years old
The str() call is needed because + cannot join a string and an integer. Without it, Python raises a TypeError.
Gotchas
A typo creates a new attribute
Because assignment creates attributes, a misspelled name does not raise an error:
dog.nmae = "Max"
print(vars(dog))
{'name': 'Rex', 'age': 4, 'nmae': 'Max'}
The dog now has a stray nmae attribute, and name is still "Rex". Python will not warn you, so read attribute names carefully. This is one reason the next lesson introduces a constructor, which sets all the attributes in one place.
Attributes set on an object are not shared
Setting rex.name never changes luna.name. Each assignment touches only the object on the left of the dot.
An attribute set on the class is shared, until an object overrides it
You can also put an attribute directly in the class body. Every object can read it, because Python looks on the object first and then on the class:
class Dog:
legs = 4
rex = Dog()
luna = Dog()
rex.legs = 3
print(rex.legs, luna.legs, Dog.legs)
3 4 4
The assignment rex.legs = 3 created a new attribute on rex only. It did not touch the class, so luna and Dog still see 4. This lesson's exercise sets attributes on the object, which is the usual choice for data that differs between objects, such as a name or an age.
Attributes can be removed
The statement del dog.age removes an attribute from one object. It is rarely needed, but it shows that an attribute is just an entry on that object, and that reading it afterwards raises AttributeError again.
Key takeaways
- An attribute is data attached to an object. Python needs no declaration; assigning with the dot operator creates it.
- Read an attribute with the same dot syntax. Reading one that does not exist raises
AttributeError. - Every object has its own set of attributes.
- Misspelling a name in an assignment silently creates a new attribute.