A developer wants to ensure that a class attribute is shared among all instances but cannot be modified from outside the class. Which approach is most appropriate?
Trap 1: Use a property decorator on a class method
Applying @property to a method intended to be shared treats it as an instance-level data descriptor: accessing it on the class yields the property object itself, not a value, and accessing it on an instance invokes the getter with that instance, so it cannot expose a single class-wide value. It also offers no write protection for the underlying class attribute, which can still be reassigned directly via the class name. Thus it neither creates true shared state nor enforces read-only access.
Trap 2: Define a public class attribute and document it as read-only
Merely documenting a public class attribute as read-only does not add any enforcement mechanism in Python; a subsequent `ClassName.attr = value` statement will silently change it for the whole class, and `instance.attr = value` creates an instance shadow that masks the class value only for that object. Documentation cannot block assignment, so the guarantee of read-only sharing rests entirely on developer discipline, not language behavior.
Trap 3: Define an instance attribute inside __init__
An attribute assigned in `__init__` via `self.attribute = ...` lives in the instance's `__dict__`, not in the class namespace, so every new instance creates its own independent copy. Changing it on one object has no effect on other instances or on the class itself, and there is no single shared value to access from the class. This directly contradicts the requirement for a shared class attribute.
- A
Use a property decorator on a class method
Why wrong: Applying @property to a method intended to be shared treats it as an instance-level data descriptor: accessing it on the class yields the property object itself, not a value, and accessing it on an instance invokes the getter with that instance, so it cannot expose a single class-wide value. It also offers no write protection for the underlying class attribute, which can still be reassigned directly via the class name. Thus it neither creates true shared state nor enforces read-only access.
- B
Define a public class attribute and document it as read-only
Why wrong: Merely documenting a public class attribute as read-only does not add any enforcement mechanism in Python; a subsequent `ClassName.attr = value` statement will silently change it for the whole class, and `instance.attr = value` creates an instance shadow that masks the class value only for that object. Documentation cannot block assignment, so the guarantee of read-only sharing rests entirely on developer discipline, not language behavior.
- C
Define an instance attribute inside __init__
Why wrong: An attribute assigned in `__init__` via `self.attribute = ...` lives in the instance's `__dict__`, not in the class namespace, so every new instance creates its own independent copy. Changing it on one object has no effect on other instances or on the class itself, and there is no single shared value to access from the class. This directly contradicts the requirement for a shared class attribute.
- D
Define a private class attribute (e.g., __shared) and provide a class method to access it
Defining `__shared` inside the class body but outside `__init__` puts it in the class namespace, and Python's name mangling rewrites it to `_ClassName__shared`, which discourages accidental external access. A `@classmethod` getter (for example `cls.__shared`) can return the value to all callers without exposing a writable descriptor; while a determined caller could still use the mangled name, the mangling plus getter signals that the attribute is private and read-only. This achieves shared state across every instance and gives a single controlled access point.