How to recognize a attribute change when the attribute is a list of objects

Related searches

How is it possible that the rectangle-object listens to the Points attributes x and y and if they change, the rectangle-object recalculates the area?

If I do it with setters and getters, every time I access the area attribute, the area will be recalculated. If the calculation is very expensive (I do some more stuff here) this is not an optimal solution for me. Is it possible to listen to the Points, only recalculating the area if they change?

I have a class called Rectangle and a class called Point:

class Point(object):

    def __init__(self, x, y):
        self.x = x
        self.y = y


class Rectangle(object):

    def __init__(self, points=None):
        self.points = [] if points is None else points
        self.area = self.calc_area()

    def calc_area(self):
        return (self.points[0].x - self.points[1].x) * (self.points[0].y - self.points[1].y)

Then I create two points and a rectangle with the two points:

# create the points:
points = list()
points.append(Point(0,0))
points.append(Point(1,1))

# create the rectangle:
rect = Rectangle(points)
print(rect.area)

Now I change the coordinates of the first point:

# change the points coordinates:
points[0].x = 0.5
points[0].y = 0.5

# Now the area should be recalculated.
print(rect.area)

Solution:

You can declare area as property.

class Rectangle(object):
    def __init__(self, points=list()):
        self.points = points
        # self.area = self.calc_area() -- removed

    @property
    def area(self):
        return = (self.points[0].x - self.points[1].x) * (self.points[0].y - self.points[1].y)

It will solve problem.

Upd.

If you want area to be recalculated only if values changed, you can use custom flag and set it on property setter.

Code:

class Point(object):
    def __init__(self, x, y):
        self._x = x
        self._y = y
        self.updated = True

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self.updated = True
        self._x = value

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        self.updated = True
        self._y = value


class Rectangle(object):
    def __init__(self, points=None):
        self.points = [] if points is None else points
        self._area = 0

    @property
    def area(self):
        if any(point.updated for point in self.points):
            self._area = (self.points[0].x - self.points[1].x) * (self.points[0].y - self.points[1].y)
            for point in self.points:
                point.updated = False
            print("recalculated") # delete it, it's just for test
        return self._area


points = [Point(0, 0), Point(1, 1)]

rect = Rectangle(points)
print(rect.area)
print(rect.area)

points[0].x = 0.5
points[0].y = 0.5

print(rect.area)

Output:

recalculated
1
1
recalculated
0.25

16. Sets of objects — How to Think Like a Computer Scientist , You can also create objects that contain lists (as attributes); you can create lists that that compare values and determine when one is greater than, less than,� Change Attribute Layer Click Schematic tabEdit Components panelModify Attributes drop-downChange Attribute Layer. Find Specify the target layer: Type the name in the box. Click List to select from a list of layers in the active drawing. Click Wires to change to the layer used for wire numbers on wires. The default layer is WIRENO

Classes - Object-Oriented Programming in Python, A class is a kind of data type, just like a string, integer or list. In some languages you must provide a list of the object's attributes in the class Setters can be inconvenient because they don't allow use of compound assignment operators: that we can change the way that an attribute is generated inside the object without� List<Audit> auditList My list is "auditList", It contains Audit objects, In this auditList I want to chnge one attribute for ex: I want to change userId value to "3" in all objects, How can I do it once, Is there any solution please Help Me

Thank you @OlvinRoght, I think the question in your link is the best solution to do this. So now I implemented a observer-pattern. Here I can bind every point in Rectangle points list to the update function.

class Point(object):

    def __init__(self, x, y):
        self._x = x
        self._y = y
        self._observers = []

    @property
    def x(self):
        return self._x

    @property
    def y(self):
        return self._y

    @x.setter
    def x(self, value):
        self._x = value
        for callback in self._observers:
            print('announcing change')
            callback()

    @y.setter
    def y(self, value):
        self._y = value
        for callback in self._observers:
            print('announcing change')
            callback()

    def bind_to(self, callback):
        print('bound')
        self._observers.append(callback)


class Rectangle(object):

    def __init__(self, points=None):
        self.points = [] if points is None else points
        self.area = []

        for point in self.points:
            point.bind_to(self.update_area)
        self.area = (self.points[0].x - self.points[1].x) * (self.points[0].y - self.points[1].y)

    def update_area(self):
        print('updating area')
        self.area = (self.points[0].x - self.points[1].x) * (self.points[0].y - self.points[1].y)


if __name__ == '__main__':

    # create points:
    points = list()
    points.append(Point(0, 0))
    points.append(Point(1, 1))

    # create the rectangle:
    rect = Rectangle(points)
    print('Area = {}'.format(rect.area))

    # change point coordinates
    points[0].x = 0.5
    points[0].y = 0.5
    print('Area = {}'.format(rect.area))

    # change point coordinates again:
    points[0].x = 0.25
    points[0].y = 0.25
    print('Area = {}'.format(rect.area))

    # just print the area; the area is not recalculated:
    print('Area = {}'.format(rect.area))

Output:

Area = 1
announcing change
updating area
announcing change
updating area
Area = 0.25
announcing change
updating area
announcing change
updating area
Area = 0.5625
Area = 0.5625

Object Type Attributes - Insight Documentation, Attribute types are used to determine the attribute field's behavior. There are a few object in Insight. You are allowed to change the label to any TEXT attribute. For example, metaclass attributes are not in the result list when the argument is a class. A function like the following tends to be more complete, although there's no guarantee of completeness since the list returned by dir() can be affected by many factors including implementing the __dir__() method, or customizing __getattr__() or

attributes: Object Attribute Lists, Unlike attr it is not an error to set attributes on a NULL object: it will first be coerced to an empty list. Note that some attributes (namely class , comment , dim ,� The attributes collection is iterable and has all the attributes of the element (standard and non-standard) as objects with name and value properties. Property-attribute synchronization. When a standard attribute changes, the corresponding property is auto-updated, and (with some exceptions) vice versa.

Change Attribute (CHGATR), An object name pattern can be used to change a single attribute for a group of *HIDDEN: Whether the object can be displayed using an ordinary directory list. will dynamically determine the optimal auxiliary storage allocation for the object, � Class and Instance Attributes Class Attributes. Instance attributes are owned by the specific instances of a class. That is, for two different instances, the instance attributes are usually different. You should by now be familiar with this concept which we introduced in our previous chapter. We can also define attributes at the class level.

Using Attributes to Compare and Group Objects . Attributes are especially important in early childhood math lessons, where students must grasp a core understanding of how similar shapes and patterns can help group objects together, where they can then be counted and combined or divided equally into different groups.

Comments
  • Take a loop at property setters, that might help you.
  • Thank you very much, your solution works! But do you know a way without modifying the Point class?
  • @MaxxiKing, there's a way to declare class, based on list and check for modifications in this class. There's also a way to backup last values and check them. There're lot of other ways how to do this, but main idea is the same - you should somehow save that variable have been modified and check for "midified" state.
  • Thank you for your suggestion! But if I do it with setters and getters, every time I access the area attribute, the area will be recalculated. If the calculation is very expensive (I do some more stuff here) this is not an optimal solution for me. Is it possible to listen to the Points, only recalculating the area if they change?
  • If you use setters and getters for x and y, it will only update the area if x or y change...