0%

Protecting Valid Object State · practice

Control Changes with Property Setters

Everything so far has pushed in one direction: fewer ways for the outside world to write to an . Lesson 2 refused bad construction, Lesson 3 replaced with events, and Lesson 5 made the score readable but not writable.

Sometimes a genuinely should be changeable. A timer’s duration might be adjusted after a review. Someone simply changed their mind.

A property that accepts a value

A property can define a second half that runs when someone assigns to it:

Try it

The reading half is @property. The writing half is @minutes.setter, named after the property it belongs to. Both are called minutes: one runs during reading and the other during assignment. Notice that __init__ uses self.minutes = minutes, too, so construction cannot bypass the rule.

Now an invalid assignment is refused:

timer.minutes = 0

The class inspects the value before storing it. If the check raises, the assignment never happens and the old valid value remains.

What does Python do when a program runs timer.minutes = 5?

Use a setter deliberately

Wrapping every attribute in a property adds code without adding safety. Reach for a setter when both hold:

  • callers genuinely need to assign this one attribute;

  • the attribute has a rule worth enforcing.

A score computed from recorded answers fails the first condition, so it stays read-only. In the exercise, a question’s adjustable point value meets both.

The exercise adds one justified setter and checks the load-bearing failure case: a refused assignment leaves the previous value untouched. The next lesson handles a different problem: one real change that must update several attributes together.

Task

Give points a setter that refuses any of zero or less, raising . Reading question.points should keep working as before. Route the constructor’s initial value through the same setter so invalid questions cannot bypass the rule during construction.

Run the program. The refused should report its message and leave the question’s previous point value exactly as it was.