How should a custom class make its data available? An attribute is a named value associated with an object and accessed with dot notation, such as `task.title`. Attributes let an instance carry the data an application needs; methods provide related operations. A `Task` might carry a title, description, urgency, status, and tags. section 8.0 section 8.1.3
Set the essential attributes in `__init__` using constructor arguments: `self.title = title`. Give every other intended instance attribute an initial value there too, even if a method will update it later. An attribute first assigned by `complete()` will raise `AttributeError` if code reads it before calling that method. Initializing it as `self.status = "created"` makes the instance’s shape predictable. section 8.1.2 section 8.1.3
Listing 8.3 Setting all attributes in __init__
class Task:
def __init__(self, title, desc, urgency):
self.title = title
self.desc = desc
self.urgency = urgency
self.status = "created"
self.tags = []
def complete(self):
self.status = "completed"
def add_tag(self, tag):
self.tags.append(tag)
The `Task` listing initializes status and tags alongside its required data, then updates them in methods. section 8.1.3
Inspect an instance
After `task = Task("Laundry", "Wash clothes", 3)`, `task.__dict__` shows its stored instance attributes: `{'title': 'Laundry', 'desc': 'Wash clothes', 'urgency': 3, 'status': 'created', 'tags': []}`. To discover an unfamiliar object’s available names, call `dir(obj)`; this can reveal extra attributes on a partial function. section 8.1.3 section 7.5.4
Direct access is usually the simplest choice. When callers must read a value but not assign it, `@property` exposes a method through the same dot notation: `task.status` reads an internally managed `_status`, while `task.status = "completed"` raises `AttributeError`. Add a property setter when assignments need validation, such as restricting status to allowed values. Avoid getters and setters that add no such control. section 8.3.3 section 8.3.4
A property can also delay expensive work until its value is requested, then retain the result in an internal attribute. Although properties and attributes share dot notation, a property is not strictly an attribute. That shared access form can preserve `user.initials` when replacing an existing attribute with a property. section 9.4.3 section 9.4.5
Attributes can connect objects as well as store simple values: `student.account.balance` reaches an account object held by a student object. Keep attributes aligned with each class’s purpose; use a shared class attribute when instances all share the same value. section 9.5.3 section 8.6

























