pandas 缺少 1 个必需的仅关键字参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48814875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Missing 1 Required Keyword-Only Argument
提问by amita00
When I try to enter a dataframe as a function parameter in Python 3.6, I'm getting the error 'Missing 1 Required Keyword-Only Argument' for the following function, where df is a dataframe and rel_change is an array:
当我尝试在 Python 3.6 中输入数据帧作为函数参数时,出现以下函数的错误“缺少 1 个必需的仅关键字参数”,其中 df 是数据帧,而 rel_change 是数组:
def get_mu(*rel_change, df):
row_count = len(df.index)
print("mu count")
print(row_count)
mu_sum = 0
for i in range (0, len(rel_change)):
mu_sum += rel_change[i]
mu = (mu_sum) / row_count
return mu
Then I access it like
然后我访问它就像
mu = get_mu(g, df)
which gives the error.
这给出了错误。
I've also tried writing the dataframe access in another function that just calculates row_count, and passing that into mu, but that gives the same error. What could I be doing wrong?
我还尝试在另一个仅计算 row_count 的函数中编写数据帧访问,并将其传递给 mu,但这会产生相同的错误。我可能做错了什么?
回答by Adam Barnes
You have defined a function with a variable amount of positional arguments, *rel_change
, which can only ever be followed by keyword only arguments. In this case, you have to pass df
by name like so:
您已经定义了一个带有可变数量的位置参数的函数,*rel_change
,只能跟在关键字参数之后。在这种情况下,您必须df
像这样按名称传递:
mu = get_mu(g, df=df)
Or redefine get_mu()
such that df
appears before *rel_change
.
或重新定义get_mu()
,使得df
之前出现*rel_change
。
回答by ZaxR
You should flip your arguments to be get_mu(df, *rel_change)
. Don't forget to flip the function call as well: get_mu(df, g)
. Optional positional arguments (often called star args in reference to the conventional name for the parameter, *args) need to go after keyword arguments.
你应该把你的论点翻转为get_mu(df, *rel_change)
。也不要忘记翻转函数调用:get_mu(df, g)
. 可选的位置参数(通常称为星形参数参考参数的常规名称 *args)需要放在关键字参数之后。
For more detail, I strongly recommend the book "Effective Python: 59 Specific Ways to Write Better Python" by Brett Slatkin. Here's an excerpt on that topic following the break:
有关更多详细信息,我强烈推荐 Brett Slatkin 所著的《Effective Python: 59 Specific Ways to Write Better Python》一书。以下是休息后关于该主题的摘录:
Item 18: Reduce Visual Noise with Variable Positional Arguments
第 18 项:使用可变位置参数减少视觉噪音
Accepting optional positional arguments (often called star args in reference to the conventional name for the parameter, *args) can make a function call more clear and remove visual noise.
接受可选的位置参数(通常称为星形参数参考参数的常规名称 *args)可以使函数调用更加清晰并消除视觉干扰。
For example, say you want to log some debug information. With a fixed number of arguments, you would need a function that takes a message and a list of values.
例如,假设您想记录一些调试信息。对于固定数量的参数,您需要一个接收消息和值列表的函数。
def log(message, values):
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print('%s: %s' % (message, values_str))
log('My numbers are', [1, 2])
log('Hi there', [])
>>>
My numbers are: 1, 2
Hi there Having to pass an empty list when you have no values to log is cumbersome and noisy. It'd be better to leave out the second argument entirely. You can do this in Python by prefixing the last positional parameter name with *. The first parameter for the log message is required, whereas any number of subsequent positional arguments are optional. The function body doesn't need to change, only the callers do.
您好,当您没有要记录的值时,必须传递一个空列表既麻烦又嘈杂。最好完全忽略第二个参数。您可以在 Python 中通过在最后一个位置参数名称前加上 * 来做到这一点。日志消息的第一个参数是必需的,而任意数量的后续位置参数是可选的。函数体不需要改变,只有调用者需要改变。
def log(message, *values): # The only difference
if not values:
print(message)
else:
values_str = ', '.join(str(x) for x in values)
print('%s: %s' % (message, values_str))
log('My numbers are', 1, 2)
log('Hi there') # Much better
>>>
My numbers are: 1, 2
Hi there
If you already have a list and want to call a variable argument function like log, you can do this by using the * operator. This instructs Python to pass items from the sequence as positional arguments.
如果您已经有一个列表并且想要调用一个变量参数函数,例如 log,您可以使用 * 运算符来执行此操作。这指示 Python 将序列中的项目作为位置参数传递。
favorites = [7, 33, 99]
log('Favorite colors', *favorites)
>>>
Favorite colors: 7, 33, 99
There are two problems with accepting a variable number of positional arguments.
接受可变数量的位置参数有两个问题。
The first issue is that the variable arguments are always turned into a tuple before they are passed to your function. This means that if the caller of your function uses the * operator on a generator, it will be iterated until it's exhausted. The resulting tuple will include every value from the generator, which could consume a lot of memory and cause your program to crash.
第一个问题是变量参数在传递给你的函数之前总是变成一个元组。这意味着如果函数的调用者在生成器上使用 * 运算符,它将被迭代直到耗尽。生成的元组将包含生成器中的每个值,这可能会消耗大量内存并导致程序崩溃。
def my_generator():
for i in range(10):
yield i
def my_func(*args):
print(args)
it = my_generator()
my_func(*it)
>>>
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Functions that accept *args are best for situations where you know the number of inputs in the argument list will be reasonably small. It's ideal for function calls that pass many literals or variable names together. It's primarily for the convenience of the programmer and the readability of the code.
接受 *args 的函数最适合您知道参数列表中的输入数量相当少的情况。它非常适合将许多文字或变量名称一起传递的函数调用。它主要是为了程序员的方便和代码的可读性。
The second issue with *args is that you can't add new positional arguments to your function in the future without migrating every caller. If you try to add a positional argument in the front of the argument list, existing callers will subtly break if they aren't updated.
*args 的第二个问题是,如果不迁移每个调用者,就无法在将来向函数添加新的位置参数。如果您尝试在参数列表的前面添加一个位置参数,则现有调用者如果没有更新就会巧妙地中断。
def log(sequence, message, *values):
if not values:
print('%s: %s' % (sequence, message))
else:
values_str = ', '.join(str(x) for x in values)
print('%s: %s: %s' % (sequence, message, values_str))
log(1, 'Favorites', 7, 33) # New usage is OK
log('Favorite numbers', 7, 33) # Old usage breaks
>>>
1: Favorites: 7, 33
Favorite numbers: 7: 33
The problem here is that the second call to log used 7 as the message parameter because a sequence argument wasn't given. Bugs like this are hard to track down because the code still runs without raising any exceptions. To avoid this possibility entirely, you should use keyword-only arguments when you want to extend functions that accept *args (see Item 21: “Enforce Clarity with Keyword-Only Arguments”).
这里的问题是第二次调用 log 使用 7 作为消息参数,因为没有给出序列参数。像这样的错误很难追踪,因为代码仍在运行而不会引发任何异常。为了完全避免这种可能性,当您想要扩展接受 *args 的函数时,您应该使用仅关键字参数(请参阅第 21 条:“使用仅关键字参数确保清晰性”)。
Things to Remember
要记住的事情
- Functions can accept a variable number of positional arguments by using *args in the def statement.
- You can use the items from a sequence as the positional arguments for a function with the * operator.
- Using the * operator with a generator may cause your program to run out of memory and crash.
- Adding new positional parameters to functions that accept *args can introduce hard-to-find bugs.
- 通过在 def 语句中使用 *args,函数可以接受可变数量的位置参数。
- 您可以使用序列中的项作为带有 * 运算符的函数的位置参数。
- 将 * 运算符与生成器一起使用可能会导致程序内存不足和崩溃。
- 向接受 *args 的函数添加新的位置参数可能会引入难以发现的错误。