Skip to content Skip to sidebar Skip to footer

Pythonic Alternative To Dict-style Setter?

People tend to consider getters and setters un-Pythonic, prefering to use @property instead. I'm currently trying to extend the functionality of a class that uses @property to sup

Solution 1:

What you describe is not a case for properties. Properties are for allowing obj (or rather, its class) to customize the behavior of obj.prop = value. If you want to customize obj.prop[key] = value, then you need to handle that not in obj but in obj.prop, which means you need to make obj.prop be a custom class. What you want here is to create a custom class with a __setitem__.

classFoo(object):def__init__(self):
        self._vals = {}

    def__setitem__(self, key, val):
        do_side_effect(key, val)
        self._vals[key] = val

Then in your MyClass's __init__, do self.foo = Foo().

If you want this dict-like object to know what its parent object is (e.g., because the side effect should take place on the parent, then pass the parent as an argument to Foo:

classFoo(object):def__init__(self, parent):
        self.parent = parent
        self._vals = {}

    def__setitem__(self, key, val):
        parent.do_side_effect(key, val)
        self._vals[key] = val

And then in MyClass.__init__ you do self.foo = Foo(self).

With regard to getters/setters, what you're doing is not a typical getter/setter. The kind of thing that is discouraged is things like getSomeProp() and setSomeProp(value), where there is a separate method for each property that you get/set. In your example, you're describing something different, which is a generalized get/set mechanism for setting key-value pairs (which presumably have some meaning for the object's behavior). Having a method setPair(key, value) is not any worse than having a method called doSomething(arg1, arg2). Here you have an extra parameter, so your task doesn't fit into the simple pattern of obj.key = value. You also have an extra layer of indirection if you want the key/value inobj.prop[key] = value to "know about" obj; in an assignment like obj.prop[key] = value, the key and value are one step removed from obj and interact directly only with prop.

You could also do it with a simple method as John Smith Optional suggests. Whether you want to do it that way or with a custom object like I described depends on how you want the API set up. There can be readability benefits to having the code built around custom "data-holding" classes like the one I outlined here, but it does make the implementation a bit more complex.

Post a Comment for "Pythonic Alternative To Dict-style Setter?"