1

In the following code I have an object with two fields: a dictionary and an aggregator. The aggregator's goal is to give the sum of dictionary values in O(1) time. I thought to use properties in order to control the access to the fields, but the dict setter is never called:

class C:
    def __init__(self):
        self._p = dict()
        self._sum_of_p_values = 0

    def get_p(self):
        print('getting p')
        return self._p
    def set_p(self, v):
        print('setting p')
        self._p = v
        print('updating the sum')
        self._sum_of_p_values = sum(self._p.values())
    def get_sum_of_values(self):
        return self._sum_of_p_values
    p = property(get_p, set_p, None, None)
    sum_of_values = property(get_sum_of_values, None, None, None) #read-only property

c = C()
c.p['a'] = 1 #value created, expect to update the aggregator
c.p['b'] = 2.14 #value created, expect to update the aggregator
# I want c.sum_of_values to be 3.14
print(c.sum_of_values)

This is the output of the above code:

getting p
getting p
0

What is the best way to achieve my goal?

1 Answer 1

0

You are directly setting the properties instead of using your setter method. Try this one:

class C:
    def __init__(self):
        self._p = dict()
        self._sum_of_p_values = 0

    def get_p(self):
        print('getting p')
        return self._p
    def set_p(self, k, v):
        print('setting p')
        self._p[k] = v
        print('updating the sum')
        self._sum_of_p_values = sum(self._p.values())
    def get_sum_of_values(self):
        return self._sum_of_p_values
    p = property(get_p, set_p, None, None)
    sum_of_values = property(get_sum_of_values, None, None, None) #read-only property

c = C()

c.set_p('a', 1)  #value created, expect to update the aggregator
c.set_p('b', 2.14) #value created, expect to update the aggregator
# I want c.sum_of_values to be 3.14
print(c.sum_of_values)

If you don't want to call your setter directly, you can use this approach:

https://stackoverflow.com/a/5021107/2011147

Sign up to request clarification or add additional context in comments.

1 Comment

you are correct, I don't want to call setter directly, I want to keep the "clean" syntax. Otherwise one needs to remove the property definition for p in order to make sure no confusion is made.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.