def track_attributes(cls):
    class TrackedWrapper:
        def __init__(self, value, count):
            self.__dict__['_value'] = value
            self.count = count

        def __getattr__(self, name):
            return getattr(self._value, name)

        # Basic "Classical" representation
        def __str__(self): return str(self._value)
        def __repr__(self): return repr(self._value)
        
        # Delegation for math/logic
        def __bool__(self): return bool(self._value)
        def __int__(self): return int(self._value)
        def __add__(self, other): return self._value + other
        def __radd__(self, other): return other + self._value

    def __setattr__(self, name, value):
        # 1. Use object.__getattribute__ to safely check for internal dicts
        try:
            counts = object.__getattribute__(self, '_attr_counts')
            values = object.__getattribute__(self, '_attr_values')
        except AttributeError:
            # Initialize storage if it doesn't exist yet
            object.__setattr__(self, '_attr_counts', {})
            object.__setattr__(self, '_attr_values', {})
            counts = object.__getattribute__(self, '_attr_counts')
            values = object.__getattribute__(self, '_attr_values')

        if name in ('_attr_counts', '_attr_values'):
            object.__setattr__(self, name, value)
            return
        
        counts[name] = counts.get(name, 0) + 1
        values[name] = value

    def __getattribute__(self, name):
        # 2. Immediate bypass for internal storage and dunder methods
        if name in ('_attr_counts', '_attr_values', '__dict__') or name.startswith('__'):
            return object.__getattribute__(self, name)
        
        try:
            counts = object.__getattribute__(self, '_attr_counts')
            values = object.__getattribute__(self, '_attr_values')
        except AttributeError:
            return object.__getattribute__(self, name)

        # 3. Handle specific logic for tracked attributes
        if name in counts:
            return TrackedWrapper(values.get(name), counts[name])
        
        # 4. Unknown attribute logic
        class Unknown:
            def __getattr__(self, attr):
                if attr == "count": return -1
                raise AttributeError(f"'{cls.__name__}' object has no attribute '{name}'")
        
        # If we reach here, the attribute isn't in our tracker. 
        # We return the Unknown proxy only if the user is about to ask for .count
        return Unknown()

    def __delattr__(self, name):
        counts = object.__getattribute__(self, '_attr_counts')
        values = object.__getattribute__(self, '_attr_values')
        if name in values:
            counts[name] = -2
            values[name] = -2

    cls.__setattr__ = __setattr__
    cls.__getattribute__ = __getattribute__
    cls.__delattr__ = __delattr__
    return cls

@track_attributes
class A:
    def __init__(self, x):
        self.x = x

a = A(4.2)

a.x = 5.5
a.x=  -2
print(a.x, a.x.count)
a.y = -1
print(a.y.count)
a.y = 2
print(a.y.count)
del a.x
print(a.x.count)

Embed on website

To embed this program on your website, copy the following code and paste it into your website's HTML: