Phil
Phil

Reputation: 642

Returning a Mutable Argument From A Python Function

Looking for some style clarification on Python function design.

I understand that Python is "pass reference by value" in its function call semantics, however I still often see code where people have returned a mutable object they've done work on within the function. A simple example:

def example(pandasDataframe):
    pandasDataframe['New Col'] = pandasDataframe['Current Col'] + 'Foo'
    return pandasDataframe

And then the function is used like this

df = example(df)

To me, this is a waste of time as both the return statement and the assignment in the call are simply not required (for mutable objects). Yet this is a very common idiom (particularly in Pandas code)

Is this a recognised/formal convention when coding in Python?

I'm wondering if this is regarded as laudable defensive programming, or at least some of the time a lack of understanding by some programmers?

Can anyone clarify any formal rules, or if this is left to the developer as a matter of personal taste/opinion?

Upvotes: 0

Views: 452

Answers (2)

Pak Uula
Pak Uula

Reputation: 3435

Phil, this idiom is called Method Chaining.

In your case you can apply a DataFrame method directly to the result of example function. E.g.

mean_val = example(DataFrame.from_dict(some_dict)).applymap(some_func)["some_field"].mean()

Without chaining you need to write something like this:

tmp_fame = DataFrame.from_dict(some_dict)
example(tmp_frame)
tmp_frame = tmp_frame.applymap(some_func)
tmp_slice = tmp_frame["some_field"]
mean_val = tmp_slice.mean()

Upvotes: 3

alecor Dev
alecor Dev

Reputation: 354

My 2 cents on this:

To start, Python is easier thought as pass by object. The reason behind those statements (pass by value, pass by reference, etc) is that the context assumes to be C/Java as a way to define something we can all agree upon. But when something new comes around that cannot be defined by the current conventions or concepts, it produces this kind of debate.

My answer goes back to design and programming paradigms and assumptions that depend on backgrounds and how people are used to develop software.

Functional programming (pure functions) answer some of these. Object oriented allows what is possible in Python with mutability (and in a way directly related to your question).

Python enables many paradigms to be used, and gives a lot of power (which should be used wisely), and that is why Python relies on many conventions.

I would say that returning a value (such as in your case) is a good approach as it is clear, explicit and easier to maintain and refactor (Explicit is better than implicit.; If the implementation is hard to explain, it's a bad idea.)

Upvotes: 0

Related Questions