Question:
How to track the change of variable in Python?

Summary:

Tracking changes to variables in Python can be done in several ways, depending on what specifically you want to achieve. Here we are doing this from a descriptor. 


You can take advantage of the fact that a descriptor can know the name of the attribute to which it is bound via the __set_name__ method, and use that to maintain attributes on the target object:


Solution:

class TrackedValidatedInteger:

    def __init__(self, min_value=None, max_value=None):

        self.min_value = min_value

        self.max_value = max_value

        self.has_changed = False

        self.value = None


    def __set_name__(self, obj, name):

        self.name = name

        setattr(obj, f"{self.name}_changed", False)


    def __get__(self, obj, objecttype=None):

        return self.value


    def __set__(self, obj, value):

        if (self.min_value is not None and value < self.min_value) or (

            self.max_value is not None and value > self.max_value

        ):

            raise ValueError(

                f"{value} must be >= {self.min_value} and <= {self.max_value}"

            )

        self.value = value

        setattr(obj, f"{self.name}_changed", True)


Given the above implementation, we can create a class Example like this:

class Example:

    v1 = TrackedValidatedInteger()

    v2 = TrackedValidatedInteger()


And then observe the following behavior:

>>> e = Example()

>>> e.v1_changed

False

>>> e.v1 = 42

>>> e.v1_changed

True

>>> e.v2_changed

False

>>> e.v2 = 0

>>> e.v2_changed

True


Instead of maintaining a per-attribute <name>_changed variable, you could instead maintain a set of changed attributes:

class TrackedValidatedInteger:

    def __init__(self, min_value=None, max_value=None):

        self.min_value = min_value

        self.max_value = max_value

        self.has_changed = False

        self.value = None


    def __set_name__(self, obj, name):

        self.name = name

        if not hasattr(obj, "_changed_attributes"):

            setattr(obj, "_changed_attributes", set())


    def __get__(self, obj, objecttype=None):

        return self.value


    def __set__(self, obj, value):

        if (self.min_value is not None and value < self.min_value) or (

            self.max_value is not None and value > self.max_value

        ):

            raise ValueError(

                f"{value} must be >= {self.min_value} and <= {self.max_value}"

            )

        self.value = value

        obj._changed_attributes.add(self.name)




In that case, we get:

>>> e = Example()

>>> e._changed_attributes

set()

>>> e.v1 = 1

>>> e._changed_attributes

{'v1'}

>>> e.v2 = 1

>>> e._changed_attributes

{'v1', 'v2'}


Also, you can iterate over e._changed_attributes if you need to record all your changed values.


Explanation: 

In the above codes, TrackedVariable is a descriptor class that tracks changes to the variable it is assigned to. The __get__ method is called when accessing the variable, and the __set__ method is called when setting the variable. Within the __set__ method, you can perform actions to track changes, such as printing a message indicating the old and new values.


When you assign tracked_var to an instance of MyClass, it becomes an instance of the TrackedVariable descriptor. Whenever you set or get the value of tracked_var through an instance of MyClass, the corresponding __set__ or __get__ method of the descriptor is invoked, allowing you to track changes as needed.


Answered by: >larsks

Credit: >Stackoverflow


Suggested blogs:

>How .transform handle the splitted groups?

>Can I use VS Code's launch config to run a specific python file?

>Python: How to implement plain text to HTML converter?

>How to write specific dictionary list for each cycle of loop?

>Reading a shapefile from Azure Blob Storage and Azure Databricks

>How to replace a value by another in certain columns of a 3d Numpy array?

>How to fix "segmentation fault" issue when using PyOpenGL on Mac?


Submit
0 Answers

What Our Clients Say About Us

Client satisfaction is our ultimate goal. Here are some kind words of our precious clients they have used to express their satisfaction with our service.

Why Choose Us ?

We endow businesses with flexible engagement models based on their unique needs. Our strength lies in state-of-the-art technology and affordable consulting services. Try us for fast POCs, full-fledged applications, or technology consulting. Always available for your service.