Menu

Sign in to track your progress and unlock all features.

Theme style

Log in

Full lesson preview

Create a Write-Once Attribute with a Property

Implement a write-once attribute on a Python class using a property and a private backing value. The attribute may be assigned only once (including allowing None) and cannot be deleted or reassigned.

Python practice25 minEncapsulation & Access PatternsAdvancedLast updated April 8, 2026

Problem statement

Design a Python class User that exposes an attribute id which can be assigned exactly once. After the first successful assignment, any further attempts to set id must raise AttributeError. Deleting id should also raise AttributeError. The property must allow assigning falsy values (like 0 or None) as a legitimate first value. Use a private (name-mangled) backing attribute and a sentinel to track whether id is still unset.

Task

Learn how to implement controlled access to internal data using properties, a private (name-mangled) backing attribute, and a sentinel to allow None as a valid first value.

Examples

Basic write-once behavior

Input

u = create_user('Alice'); u.id = 100; u.id

Output

100

The first assignment sets id to 100; reading returns 100.

Attempting a second set

Input

u = create_user('Bob'); u.id = 1; (lambda: (setattr(u, 'id', 2), 'ok'))()

Output

AttributeError

A second assignment must raise AttributeError (in real code you'd catch it).

Input format

Functions and classes are defined in the module. Tests call helper functions (e.g., create_user(name), assign_id(user, value)) and evaluate their return values.

Output format

Return values from helper functions or properties. Tests compare the string form of the returned value to the expected output.

Constraints

Implement the id attribute using a property with getter, setter, and deleter. Use a private (name-mangled) backing attribute and a sentinel to distinguish "unset" from allowed values like None. On the second set or on delete, raise AttributeError. No external libraries.

Samples

Sample 1

Input

assign_id(create_user('Zoe'), 0)

Output

0

0 is a valid value and should be stored and returned.