user10019227
user10019227

Reputation: 117

Adding a attribute to an instance

I have the below code...

import math
class Circle:
    """Class to create Circle objects"""

    def __init__(self, radius=1):
        """Circle initializer"""
        self.radius = radius

    @property
    def area(self):
        """Calculate and return the area of the Circle"""
        return math.pi * self.radius ** 2

    @property
    def diameter(self):
        """Calculate and return the diameter of the Circle"""
        return self.radius * 2

    @diameter.setter
    def diameter(self, diameter):
        """Set the diameter"""
        self.radius = diameter / 2

    def __str__(self):
        return 'Circle of radius {}'.format(self.radius)

    def __repr__(self):
        return "Circle(radius={})".format(self.radius)

I want to add an attribute radius_log to the instance. It is a list which would contain radius values which have belonged to the circle as well as the current radius value as the last item in the list. The other properties must still work. I know I have to make the radius a property and add a setter property for the radius. Below is an example output...

 circle = Circle()
    circle
Circle(radius=1)
    circle.radius_log
[1]
    circle.radius = 2
    circle.diameter = 3
    circle
Circle(radius=1.5)
    circle.radius_log
[1, 2, 1.5]
    circle2 = Circle(radius=2)
    circle2.radius_log
[2]

Any ideas on how to do this?

Upvotes: 0

Views: 388

Answers (1)

Andrej Kesely
Andrej Kesely

Reputation: 195438

Change radius to property and add new property radius_log.

Inside radius property setter you will add value to _property_log list in every change. This log will be exposed through radius_log property:

import math
class Circle:
    """Class to create Circle objects"""

    def __init__(self, radius=1):
        """Circle initializer"""
        self.radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self._radius = getattr(self, '_radius', None)
        if self._radius == value:
            return
        self._radius_log = getattr(self, '_radius_log', [])
        self._radius_log.append(value)
        self._radius = value

    @property
    def radius_log(self):
        return self._radius_log[:]

    @property
    def area(self):
        """Calculate and return the area of the Circle"""
        return math.pi * self.radius ** 2

    @property
    def diameter(self):
        """Calculate and return the diameter of the Circle"""
        return self.radius * 2

    @diameter.setter
    def diameter(self, diameter):
        """Set the diameter"""
        self.radius = diameter / 2

    def __str__(self):
        return 'Circle of radius {}'.format(self.radius)

    def __repr__(self):
        return "Circle(radius={})".format(self.radius)

circle = Circle()
print(circle)
print(circle.radius_log)   
circle.radius = 2
circle.diameter = 3
print(circle)
print(circle.radius_log)    
circle2 = Circle(radius=2)
print(circle2.radius_log)

This prints:

Circle of radius 1
[1]
Circle of radius 1.5
[1, 2, 1.5]
[2]

Upvotes: 1

Related Questions