Python Forum
Class object instance. Link instance attribute to class. Can it be done easier.
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Class object instance. Link instance attribute to class. Can it be done easier.
#3
I have objects like a pygame.Rect. It has methods and properties.
Every time it values changes. I want a callback to update a list.

Example
The problem is I have to remember to type update_point_total.
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def copy(self):
        return Point(self.x, self.y)

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

    def __add__(self, point):
        return Point(self.x + point.x, self.y + point.y)

    def __repr__(self):
        return str(vars(self))

class MyObject:
    def __init__(self, point):
        self.parent = None
        self.point = point
        self.point_total = point.copy()
        self.items = []

    def add(self, my_object):
        my_object.parent = self
        my_object.update_point_total()
        self.items.append(my_object)

    def get_points(self):
        if self.parent:
            return self.point + self.parent.get_points()
        return self.point.copy()

    def update_point_total(self):
        self.point_total = self.point.copy()

        if self.parent:
            self.point_total = self.get_points()

        self.update_all_items()

    def update_all_items(self):
        for item in self.items:
            item.update_point_total()

    def __repr__(self):
        return str(vars(self))


def main():
    a = MyObject(Point(1,1))
    b = MyObject(Point(2,2))
    c = MyObject(Point(5,5))
    d = MyObject(Point(10,10))

    a.add(b)
    c.add(d)
    a.add(c)

    print(a.point_total)
    print(b.point_total)
    print(c.point_total)
    print(d.point_total)

    # This is all over my code
    b.point.x = 5
    # If this is forgotten. Hard bug to find.
    b.update_point_total()

    c.point.y += 3
    c.update_point_total()

    print()
    print(a.point_total)
    print(b.point_total)
    print(c.point_total)
    print(d.point_total)

main()
My solution was to use a class. That holds the rect and callback. I link this rect attributes, methods, and properties to the class.
For I don't have to remember to type update after value changes.
def dir_trim(item):
    return [d for d in dir(item) if not d.startswith('__')]

class LinkProperty:
    def __init__(self, attr):
        self.attr = attr

    def __set__(self, instance, value):
        setattr(instance.read_value, self.attr, value)
        instance.callback()

    def __get__(self, instance, owner):
        return getattr(instance.read_value, self.attr)

def link_variable(value, callback):
    class LinkVariable:
        def __init__(self, value, callback):
            self.read_value = value
            self.callback = callback

        def __call__(self, value=None):
            if value is None:
                return self.read_value
            self.read_value = value
            self.callback()

        def clear(self):
            self.read_value = None
            self.callback()

    items = dir_trim(value)
    for item in items:
        setattr(LinkVariable, item, LinkProperty(item))

    return LinkVariable(value, callback)

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

    def copy(self):
        return Point(self.x, self.y)

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

    def __add__(self, point):
        return Point(self.x + point.x, self.y + point.y)

    def __repr__(self):
        return str(vars(self))

class MyObject:
    def __init__(self, point):
        self.parent = None
        self.point = link_variable(point, self.update_point_total)
        self.point_total = point.copy()
        self.items = []

    def add(self, my_object):
        my_object.parent = self
        my_object.update_point_total()
        self.items.append(my_object)

    def get_points(self):
        if self.parent:
            return self.point.read_value + self.parent.get_points()
        return self.point.copy()

    def update_point_total(self):
        self.point_total = self.point.copy()

        if self.parent:
            self.point_total = self.get_points()

        self.update_all_items()

    def update_all_items(self):
        for item in self.items:
            item.update_point_total()

    def __repr__(self):
        return str(vars(self))


def main():
    a = MyObject(Point(1,1))
    b = MyObject(Point(2,2))
    c = MyObject(Point(5,5))
    d = MyObject(Point(10,10))

    a.add(b)
    c.add(d)
    a.add(c)

    print(a.point_total)
    print(b.point_total)
    print(c.point_total)
    print(d.point_total)

    b.point.x = 5
    c.point.y += 3

    print()
    print(a.point_total)
    print(b.point_total)
    print(c.point_total)
    print(d.point_total)

main()
Is there an easier or better way to tackle this ?
99 percent of computer problems exists between chair and keyboard.
Reply


Messages In This Thread
RE: Class object instance. Link instance attribute to class. Can it be done easier. - by Windspar - Dec-03-2018, 04:17 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
Bug Copying methods to effect the new owner instead of the old instance Daniel285 2 172 Yesterday, 07:58 AM
Last Post: Gribouillis
  [split] Class and methods ebn852_pan 15 848 May-23-2024, 11:57 PM
Last Post: ebn852_pan
  [SOLVED] [listbox] Feed it with dict passed to class? Winfried 3 328 May-13-2024, 05:57 AM
Last Post: Larz60+
  Class and methods Saida2024 2 315 May-13-2024, 04:04 AM
Last Post: deanhystad
  How does this code create a class? Pedroski55 6 687 Apr-21-2024, 06:15 AM
Last Post: Gribouillis
  class definition and problem with a method HerrAyas 2 381 Apr-01-2024, 03:34 PM
Last Post: HerrAyas
  Printing out incidence values for Class Object SquderDragon 3 436 Apr-01-2024, 07:52 AM
Last Post: SquderDragon
  class and runtime akbarza 4 500 Mar-16-2024, 01:32 PM
Last Post: deanhystad
  Operation result class SirDonkey 6 677 Feb-25-2024, 10:53 AM
Last Post: Gribouillis
  The function of double underscore back and front in a class function name? Pedroski55 9 877 Feb-19-2024, 03:51 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020