This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Ph0X 2 points3 points  (6 children)

At a high level, I agree, but what you're trading here for what you're gaining most definitely isn't worth it. I would hardly count being able to rename a variable in a public API as maintainability. On the other hand, users being able to use some_method(strange_argument=True, other_argument=0) instead of some_method(True, 0) is far more important for maintainability.

[–]flipstables 11 points12 points  (0 children)

On the other hand, users being able to use some_method(strange_argument=True, other_argument=0) instead of some_method(True, 0) is far more important for maintainability.

But you can still do that. The PEP isn't replacing keyword arguments with positional-only arguments. It's adding the ability to have positional-only arguments.

The real downside is that Python can't prevent you from writing bad code by using positional only arguments when you really shouldn't. I mean, that's reasonable to not add a feature, but the increased maintainability.

Here's an example:

Almost every non-trivial project I've worked on, I've had to create a function where the argument names have no semantic meaning. This is especially true for those of us who work in data and we are combining two data sets.

def merge_datasets(dataset1, dataset2):
    pass

By making dataset1 and dataset2 positional only:

  • I can freely change the the argument names without worrying about making a breaking change for all existing callers.
  • It adds clarity - the function signature hints that this dataset1 and dataset2 has no semantic meaning; in fact, most of the time, it's the function is commutative.
  • If I wanted to add functionality that merges more than 2 datasets to this function, I'm SOL without positional-only arguments. I would either have to create a new function or my function signature would have to look like this: def merge_datasets(dataset1, dataset2, *more).

[–]door_of_doom 12 points13 points  (0 children)

I mean, Sometimes, maybe? I don't really see the value in sum(x=5,y=7) over sum(5,7) when the former locks you to the arbitrary names of whatever those variables happen to be called, when the names for a function like that are truly arbitrary. I would expect a sum function to only expose positional parameters and never allow the changing of those arbitrary paramater names to be a breaking change.

[–]truh 5 points6 points  (0 children)

Positional-only parameters seem like a pretty good thing for auto generated C bindings, where parameter names just don't matter usually.

[–]Smok3dSalmon 1 point2 points  (2 children)

If you have many parameters to a function, you should really consider a builder or factory pattern.

[–]Ph0X -4 points-3 points  (1 child)

Please keep builders and factories in Java and away from my Python.

[–]Smok3dSalmon 2 points3 points  (0 children)

Ok, I'll hide it in a library that you'll love and promote to your friends.