10: Advanced Attributes¶
Summary¶
Name mangling can provide a private attribute that is difficult to access accidentally
Using closure you can create a private variable
Properties have getter, setter and delete functions which are called when you try to work with the attribute
You can create a private property using the property object and closure
The property object has additional methods which allow it to be used as a decorator
Program¶
"""
Program: Advanced Encapsulation Techniques in Python
This program demonstrates:
1. Name mangling for private attributes
2. Closures to create private variables
3. Properties with getter, setter, and deleter
4. Private properties using closures
5. Using property() and decorator syntax
Author: Your Name
"""
# --------------------------------------------------
# 1. Name Mangling (Pseudo-private attributes)
# --------------------------------------------------
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.__balance = balance # Name mangling: _BankAccount__balance
def deposit(self, amount):
self.__balance += amount
def get_balance(self):
return self.__balance
# --------------------------------------------------
# 2. Closure for Private Variable
# --------------------------------------------------
def counter():
count = 0 # private variable via closure
def increment():
nonlocal count
count += 1
return count
return increment
# --------------------------------------------------
# 3. Properties with Getter, Setter, Deleter
# --------------------------------------------------
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
def get_celsius(self):
print("Getting value...")
return self._celsius
def set_celsius(self, value):
print("Setting value...")
if value < -273.15:
raise ValueError("Temperature below absolute zero is not possible.")
self._celsius = value
def del_celsius(self):
print("Deleting value...")
del self._celsius
# property object
celsius = property(get_celsius, set_celsius, del_celsius)
# --------------------------------------------------
# 4. Private Property Using Closure + property()
# --------------------------------------------------
def create_person(name, age):
_age = age # private via closure
def get_age(self):
return _age
def set_age(self, value):
nonlocal _age
if value < 0:
raise ValueError("Age cannot be negative")
_age = value
def del_age(self):
nonlocal _age
print("Deleting age...")
_age = None
class Person:
def __init__(self, name):
self.name = name
age = property(get_age, set_age, del_age)
return Person(name)
# --------------------------------------------------
# 5. Property Decorator Syntax
# --------------------------------------------------
class Rectangle:
def __init__(self, width, height):
self._width = width
self._height = height
@property
def area(self):
"""Getter: Calculates area"""
return self._width * self._height
@area.setter
def area(self, value):
"""Setter: Adjust width assuming height stays constant"""
print("Setting area...")
self._width = value / self._height
@area.deleter
def area(self):
"""Deleter"""
print("Deleting dimensions...")
del self._width
del self._height
# --------------------------------------------------
# MAIN DEMONSTRATION
# --------------------------------------------------
if __name__ == "__main__":
print("---- Name Mangling Example ----")
acc = BankAccount("Alice", 1000)
acc.deposit(500)
print("Balance:", acc.get_balance())
# Accessing mangled name (not recommended)
print("Access via mangled name:", acc._BankAccount__balance)
print("\n---- Closure Example ----")
my_counter = counter()
print(my_counter())
print(my_counter())
print(my_counter())
print("\n---- Property (Getter/Setter/Deleter) ----")
temp = Temperature(25)
print(temp.celsius)
temp.celsius = 30
print(temp.celsius)
del temp.celsius
print("\n---- Private Property with Closure ----")
person = create_person("Bob", 20)
print(person.name, person.age)
person.age = 25
print("Updated age:", person.age)
print("\n---- Property Decorator Example ----")
rect = Rectangle(4, 5)
print("Area:", rect.area)
rect.area = 50
print("New width after setting area:", rect._width)
del rect.area
Program Output¶
---- Name Mangling Example ----
Balance: 1500
Access via mangled name: 1500
---- Closure Example ----
1
2
3
---- Property (Getter/Setter/Deleter) ----
Getting value...
25
Setting value...
Getting value...
30
Deleting value...
---- Private Property with Closure ----
Bob 20
Updated age: 25
---- Property Decorator Example ----
Area: 20
Setting area...
New width after setting area: 10.0
Deleting dimensions...