2023-09-16 16:51:31 -04:00
|
|
|
# /usr/bin/env python3
|
|
|
|
"""set_get_attr_example.py
|
2023-09-15 12:55:39 -04:00
|
|
|
-----------------------
|
|
|
|
|
|
|
|
This module contains a class named `Number` which implements special attribute
|
|
|
|
access methods to demonstrate custom attribute setting and getting behaviors
|
|
|
|
in a Python class.
|
|
|
|
|
|
|
|
Here is a summary of its functionality and methods:
|
|
|
|
|
|
|
|
- `__init__(self, number)`: Initializes a new instance with a `number` parameter.
|
|
|
|
- `power(self)`: Squares the current value of the `_number` attribute. It utilizes
|
|
|
|
`self.number` to access the `_number` attribute, which works correctly due to
|
|
|
|
the overridden `__getattribute__` method.
|
|
|
|
- `another_func(self)`: Prints a message when invoked.
|
|
|
|
- `__str__(self)`: Returns a string representation of the `_number` attribute.
|
|
|
|
|
|
|
|
The class also overrides special methods (`__setattr__`, `__getattribute__`,
|
|
|
|
`__getattr__`) to define custom behaviors for setting, getting, and accessing
|
|
|
|
non-existent attributes, respectively.
|
|
|
|
|
|
|
|
Usage:
|
|
|
|
If run as the main program, an instance of `Number` is created with an initial
|
|
|
|
value of 5. The script then performs various operations to demonstrate the
|
|
|
|
custom attribute access behaviors.
|
|
|
|
|
|
|
|
Note:
|
|
|
|
The `__getattribute__` method in the `Number` class is implemented such that if
|
|
|
|
an attribute other than the ones listed in the `options` list is accessed, the
|
|
|
|
`_number` attribute value is returned. This is demonstrated in the script where
|
|
|
|
`number.num` and `number.number` (which are non-existing attributes) are accessed,
|
|
|
|
but the `_number` value is printed instead of raising an AttributeError.
|
|
|
|
"""
|
|
|
|
|
2023-09-16 16:51:31 -04:00
|
|
|
|
2023-08-23 11:11:51 -04:00
|
|
|
class Number:
|
|
|
|
def __init__(self, number):
|
|
|
|
self._number = number
|
|
|
|
|
|
|
|
def power(self):
|
|
|
|
self._number = self.number * self.number
|
|
|
|
|
|
|
|
def another_func(self):
|
|
|
|
print("In another function")
|
|
|
|
|
|
|
|
def __setattr__(self, name, value):
|
|
|
|
# print(name, type(name), value, type(value))
|
2023-08-23 12:02:52 -04:00
|
|
|
super().__setattr__("_number", 0)
|
2023-08-23 11:11:51 -04:00
|
|
|
try:
|
|
|
|
if isinstance(value, int):
|
2023-08-23 12:02:52 -04:00
|
|
|
super().__setattr__("_number", value)
|
2023-08-23 11:11:51 -04:00
|
|
|
elif isinstance(value, str):
|
2023-08-23 12:02:52 -04:00
|
|
|
super().__setattr__("_number", int(value))
|
2023-08-23 11:11:51 -04:00
|
|
|
except ValueError:
|
|
|
|
return
|
|
|
|
|
|
|
|
def __getattribute__(self, name):
|
2023-08-23 12:02:52 -04:00
|
|
|
options = ["power", "another_func", "__class__"]
|
2023-08-23 11:11:51 -04:00
|
|
|
if name in options:
|
|
|
|
return super().__getattribute__(name)
|
|
|
|
else:
|
2023-08-23 12:02:52 -04:00
|
|
|
return super().__getattribute__("_number")
|
2023-08-23 11:11:51 -04:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return str(self._number)
|
|
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
|
return self._number
|
2023-09-15 12:55:39 -04:00
|
|
|
|
2023-09-16 16:51:31 -04:00
|
|
|
|
2023-09-15 12:55:39 -04:00
|
|
|
if __name__ == "__main__":
|
|
|
|
number = Number(5)
|
|
|
|
print(number.num)
|
|
|
|
print(number.number)
|
|
|
|
number.power()
|
|
|
|
print(number.num)
|
|
|
|
number.another_func()
|