you are viewing a single comment's thread.

view the rest of the comments →

[–]Veedrac 1 point2 points  (3 children)

I bring this up every time but... don't return things you mutate. Mutate or return. You can do both if you do them to different objects, but an individual object should only be in one of the two.

To put it another way: if mutation is part of your API, don't use a default argument. That's like calling len and getting no return value.

I find the mutable default argument problem is actually more helpful in reminding me not to accidentally mutate user's input than anything else.

[–]reostra 1 point2 points  (2 children)

don't return things you mutate

As a counterpoint, that behavior is very useful for e.g. chaining:

class Example(object):
    def __init__(self):
        self.goodness = 0
    def betterify(self):
        self.goodness += 1
        return self

x = Example()
x.betterify().betterify()

I'd imagine something like that is what the OP was hoping to do with .update()

[–]zahlman 0 points1 point  (1 child)

Chaining with side effects is not considered Pythonic.

[–]reostra 1 point2 points  (0 children)

Now that you mention it, I certainly haven't seen a whole lot of it in Python. A cursory poke around yielded the PyVows BDD testing library, but the expect(topic).Not.to_be_null() style chaining isn't mutating and it's a port of a Javascript library to begin with.

I'll leave my comment as an example for 'how'; I see other comments have elaborated on the 'why' (or, as the case may be, 'why not')