Any reason NOT to always use keyword arguments?

2019-01-30 07:55发布

Before jumping into python, I had started with some Objective-C / Cocoa books. As I recall, most functions required keyword arguments to be explicitly stated. Until recently I forgot all about this, and just used positional arguments in Python. But lately, I've ran into a few bugs which resulted from improper positions - sneaky little things they were.

Got me thinking - generally speaking, unless there is a circumstance that specifically requires non-keyword arguments - is there any good reason NOT to use keyword arguments? Is it considered bad style to always use them, even for simple functions?

I feel like as most of my 50-line programs have been scaling to 500 or more lines regularly, if I just get accustomed to always using keyword arguments, the code will be more easily readable and maintainable as it grows. Any reason this might not be so?

UPDATE:

The general impression I am getting is that its a style preference, with many good arguments that they should generally not be used for very simple arguments, but are otherwise consistent with good style. Before accepting I just want to clarify though - is there any specific non-style problems that arise from this method - for instance, significant performance hits?

11条回答
Emotional °昔
2楼-- · 2019-01-30 08:42

If your consideration is to improve readability of function calls, why not simply declare functions as normal, e.g.

def test(x, y):
    print "x:", x
    print "y:", y

And simply call functions by declaring the names explicitly, like so:

test(y=4, x=1)

Which obviously gives you the output:

x: 1
y: 4

or this exercise would be pointless.

This avoids having arguments be optional and needing default values (unless you want them to be, in which case just go ahead with the keyword arguments! :) and gives you all the versatility and improved readability of named arguments that are not limited by order.

查看更多
太酷不给撩
3楼-- · 2019-01-30 08:43

I don't see the purpose of using keyword arguments when the meaning of the arguments is obvious

查看更多
混吃等死
4楼-- · 2019-01-30 08:47

When Python's built-in compile() and __import__() functions gain keyword argument support, the same argument was made in favor of clarity. There appears to be no significant performance hit, if any.

Now, if you make your functions only accept keyword arguments (as opposed to passing the positional parameters using keywords when calling them, which is allowed), then yes, it'd be annoying.

查看更多
萌系小妹纸
5楼-- · 2019-01-30 08:48

There isn't any reason not to use keyword arguments apart from the clarity and readability of the code. The choice of whether to use keywords should be based on whether the keyword adds additional useful information when reading the code or not.

I follow the following general rule:

  1. If it is hard to infer the function (name) of the argument from the function name – pass it by keyword (e.g. I wouldn't want to have text.splitlines(True) in my code).
  2. If it is hard to infer the order of the arguments, for example if you have too many arguments, or when you have independent optional arguments – pass it by keyword (e.g. funkyplot(x, y, None, None, None, None, None, None, 'red') doesn't look particularly nice).
  3. Never pass the first few arguments by keyword if the purpose of the argument is obvious. You see, sin(2*pi) is better than sin(value=2*pi), the same is true for plot(x, y, z).

In most cases, stable mandatory arguments would be positional, and optional arguments would be keyword.

There's also a possible difference in performance, because in every implementation the keyword arguments would be slightly slower, but considering this would be generally a premature optimisation and the results from it wouldn't be significant, I don't think it's crucial for the decision.

UPDATE: Non-stylistical concerns

Keyword arguments can do everything that positional arguments can, and if you're defining a new API there are no technical disadvantages apart from possible performance issues. However, you might have little issues if you're combining your code with existing elements.

Consider the following:

  • If you make your function take keyword arguments, that becomes part of your interface. You can't replace your function with another that has a similar signature but a different keyword for the same argument.
  • You might want to use a decorator or another utility on your function that assumes that your function takes a positional argument. Unbound methods are an example of such utility because they always pass the first argument as positional after reading it as positional, so cls.method(self=cls_instance) doesn't work even if there is an argument self in the definition.

None of these would be a real issue if you design your API well and document the use of keyword arguments, especially if you're not designing something that should be interchangeable with something that already exists.

查看更多
Deceive 欺骗
6楼-- · 2019-01-30 08:48

I remember reading a very good explanation of "options" in UNIX programs: "Options are meant to be optional, a program should be able to run without any options at all".

The same principle could be applied to keyword arguments in Python. These kind of arguments should allow a user to "customize" the function call, but a function should be able to be called without any implicit keyword-value argument pairs at all.

查看更多
登录 后发表回答