5

I have a class with a function that updates attributes of its objects. I'm trying to figure out which is more pythonic: should I explicitly return the object I'm updating, or simply update the self object?

For example:

class A(object):

    def __init__(self):
        self.value = 0

    def explicit_value_update(self, other_value):
        # Expect a lot of computation here - not simply a setter
        new_value = other_value * 2
        return new_value

    def implicit_value_update(self, other_value):
        # Expect a lot of computation here - not simply a setter
        new_value = other_value * 2
        self.value = new_value
        #  hidden `return None` statement

if __name__ == '__main__':
    a = A()
    a.value = a.explicit_value_update(2)
    a.implicit_value_update(2)

I've looked around, but haven't seen any clear answers on this.

EDIT: Specifically, I'm looking for both readability and execution time. Would there be an advantage in either category for either function?

2
  • 1
    I feel like it depends on what you're doing with self.value on your object. If the method is meant to modify the attributes of the object, do that. If it's meant to generate new attributes but keep self.value, do that. Commented Jan 20, 2015 at 0:10
  • I was thinking that it depended on whether the value should be quasi-private or quasi-public (knowing that neither really exist in Python). That is, if I expect value could be used by others, I'd return it. Maybe I should just always return the value, and get the best of both worlds? Commented Jan 20, 2015 at 0:13

2 Answers 2

1

I dont't think the first case would be considered good in any language.

Try to understand what is the purpose of the method. If the purpose is to modify the state of the object, then by all means modify it. If the purpose is to give a useful information for the caller to use, then return the value.

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

Comments

1
a.value = a.explicit_value_update(2)

looks very odd to me.

Neither of your ..._update methods had self arguments, so won't work correctly. explicit_value_update doesn't use any attributes, so should probably be a @staticmethod.

class A(object):

    def __init__(self):
        self.value = 0

    @staticmethod
    def explicit_value_update(other_value):
        return other_value * 2

This makes it clear that it's functionality related to the class, but doesn't need access to class or instance attributes.

But I think the best way to do something like this would be using a property:

class A(object):

    def __init__(self):
        self.value = 0

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, other_value):
        self._value = 2 * other_value

if __name__ == '__main__':
    a = A()
    a.value = 2
    print a.value # 4

Note that there's now no boilerplate - you just assign straight to the attribute and the setter handles it for you. It is conventional in Python to not return the object from methods that modify it in-place.

2 Comments

Whoops! I completely forgot the self attributes. They were supposed to be class methods, not static methods. Sorry! @EOL corrected my mistake. I was thinking in more general terms, when a lot of computation needs to be done to come out with a final updated class attribute. I'll edit the question accordingly.
@NickSweet the amount of computation doesn't matter here. If the state changes, update inside the method and don't return. A subsequent attribute lookup will make little difference. If you want to implement that using [instance/class/static] methods that return values, they should probably be private by convention (named with a leading underscore).

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.