Properties And Access Control

Python does not enforce private attributes in the same way as Java or C++. Instead, it uses naming conventions and properties.

Naming Conventions

Single leading underscore means internal use:

self._balance

Double leading underscores trigger name mangling and help avoid name clashes in subclasses.

Double leading and trailing underscores are reserved for Python special methods such as __init__.

Property

@property lets a method behave like an attribute.

class Customer:
    def __init__(self, name, new_bal):
        self.name = name
        if new_bal < 0:
            raise ValueError("Invalid balance!")
        self._balance = new_bal
 
    @property
    def balance(self):
        return self._balance

Setter

A setter validates assignment.

@balance.setter
def balance(self, new_bal):
    if new_bal < 0:
        raise ValueError("Invalid balance!")
    self._balance = new_bal

Properties are useful when you want user-facing attribute syntax but developer-facing control over validation or computed values.

Relation To Exceptions

Property setters often raise Python Exceptions when invalid values are assigned.