QuaternionsRock
QuaternionsRock

Reputation: 912

How to assign to a property within a lambda expression?

I have a class that is similar to the following:

class Foo:
    def __init__(self, enabled=False):
        self._event_listeners = []
        self._enabled = enabled
    
    def register_event_listener(self, event_listener):
        self._event_listeners.append(event_listener)

    @property
    def enabled(self):
        return self._enabled
    
    @enabled.setter
    def enabled(self, enabled):
        self._enabled = enabled
        for event_listener in self._event_listeners:
            event_listener(self)

Now, say I have two instances of Foo - a and b. I would like the enabled state of b to follow that of a. My initial approach was to do this:

a.register_event_listener(lambda x, y=b: (y.enabled := x.enabled))

Where I immediately discovered that assignment expressions are not legal for properties. Is there any way to accomplish this without setattr ugliness?

Upvotes: 0

Views: 85

Answers (1)

QuaternionsRock
QuaternionsRock

Reputation: 912

So, I have since discovered two solutions that don't require replacing the lambda with a def.

First, there is the obvious implementation:

a.register_event_listener(lambda x, y=b: setattr(y, 'enabled', x.enabled))

Needless to say, I am not a fan of using setattr for statically-defined attributes. Luckily, I stumbled upon an alternative:

a.register_event_listener(lambda x, y=b: type(y).enabled.fset(y, x.enabled))

Upvotes: 1

Related Questions