mjschuetze102
mjschuetze102

Reputation: 145

Calling property setter within lambda

I have a class using the property decorator for setter/getter of a variable.

class Application:

    @property
    def volume(self):
        return self._volume

    @volume.setter
    def volume(self, value):
        self._volume = value

I want to be able to set the volume of an application within a lambda.

Lambdas do not allow for statements, only expressions, so it is not as easy as just calling lambda application, value: application.volume = value.

# Things I have tried and have not worked
lambda application, value: application.volume = value    # Can't assign values in lambda
lambda application, value: application.volume(value)     # Getter is run and turned into a callable
lambda application, value: (application.volume := value) # Assignment expression can not resolve application

What I have been able to do, is change the way of defining the property

class Application:

    def get_volume(self):
        return self._volume

    def set_volume(self, value):
        self._volume = value

    volume = property(get_volume, set_volume)

Which then allows me to call the setter function directly

lambda application, value: application.set_volume(value)

This solution ignores the point of properties though. Is there a way of calling the setter within a lambda while still using the property decorator tags, or is the hack-y ignore the property and use the setter directly the best way to set the value.

Upvotes: 2

Views: 360

Answers (1)

Aplet123
Aplet123

Reputation: 35540

Use setattr:

class Application:

    @property
    def volume(self):
        print(f"volume get")
        return self._volume

    @volume.setter
    def volume(self, value):
        print(f"volume set {value}")
        self._volume = value

update_volume = lambda application, value: setattr(application, "volume", value)
x = Application()
update_volume(x, 5)
print(x.volume)

Prints:

volume set 5
volume get
5

Upvotes: 3

Related Questions