File: LP6E/Chapter38/getattr-person.py
class Person:
def __init__(self, name): # On [Person()]
self._name = name # Triggers __setattr__!
def __getattr__(self, attr): # On [obj.undefined]
print('get: ' + attr)
if attr == 'name': # Intercept name: not stored
return self._name # Does not loop: real attr
else: # Others are errors
raise AttributeError(attr)
def __setattr__(self, attr, value): # On [obj.any = value]
print('set: ' + attr)
if attr == 'name':
attr = '_name' # Set internal name
self.__dict__[attr] = value # Avoid looping here
def __delattr__(self, attr): # On [del obj.any]
print('del: ' + attr)
if attr == 'name':
attr = '_name' # Avoid looping here too
del self.__dict__[attr] # but much less common
sue = Person('Sue Jones') # sue has a managed attribute
print(sue.name) # Runs __getattr__
sue.name = 'Susan Jones' # Runs __setattr__
print(sue.name)
del sue.name # Runs __delattr__
print('-'*20)
bob = Person('Bob Smith') # bob's attrs work like sue's
print(bob.name)
#print(Person.name.__doc__) # No direct equivalent here!