函数不识别 args 和 kwargs

function not recognizing args and kwargs

我正在尝试像这样定义一个函数:

def get_event_stats(elengths, einds, *args, **kwargs):

    master_list = []

    if avg:
        for arg in args:
             do stuff...
    if tot:
        for arg in args:
             do stuff...

    return master_list

我希望 elengths 和 einds 是固定的位置参数(这些只是整数数组)。我试图通过将一个可变长度的数组列表作为 *args 和一些 **kwargs 传递给它来使用该函数,在这个例子中是两个(avg 和 tot),但可能更多,例如

avg_event_time = get_event_stats(event_lengths, eventInds, *alist, avg=True, tot=False)

哪里

alist = [time, counts]

而我的kwargs是avg和tot,分别赋值为True和False。无论我如何尝试实现此功能,我都会遇到某种错误。在正确使用 *args 和 **kwargs 时我错过了什么?

如果您的意思是 avgtot 应该作为关键字参数传入,就像在您的示例 get_event_stats(..., avg=True, tot=False) 中一样,那么它们将填充到 kwargs 中。您可以使用键查找在 kwargs 字典中查找它们(例如 kwargs['avg'].

但是,如果它们根本不存在,则会出现关键错误,因此请将其与 dict.get() 方法一起使用:kwargs.get('avg') which returns None如果不存在,则为布尔值 False。或者使用 kwargs.get('avg', False) 如果你明确想要一个 False 如果它不存在。

def get_event_stats(elengths, einds, *args, **kwargs):

    master_list = []

    if kwargs.get('avg'):
        for arg in args:
             do stuff...
    if kwargs.get('tot'):
        for arg in args:
             do stuff...

    return master_list

**kwargs 创建一个 dict,它不会将任意名称注入本地命名空间。如果要查找是否传递了特定关键字,则无法测试 if avg:(没有名为 avg 的变量),您需要检查 avg 是否在 dict,例如if 'avg' in kwargs:,或者同时检查存在和"truthiness",所以通过avg=False相当于根本不通过,测试if kwargs.get('avg'):(使用kwargs.get('avg')确保没有异常如果 avg 根本没有通过,则抛出,这与 if kwargs['avg']:) 不同。

注意:如果可能的话,您真的应该转到 Python 3。它使编写此函数更加明显和干净,因为您可以完全避免 kwargs 的需要,并且只需将函数定义为:

即可验证是否传递了无法识别的关键字参数
def get_event_stats(elengths, einds, *args, avg=False, tot=False):
    master_list = []

    if avg:
        for arg in args:
             do stuff...
    if tot:
        for arg in args:
             do stuff...

    return master_list

请注意,如果您在位置可变参数之后明确命名您的关键字参数,那么您已经编写的函数的主体如何在不修改的情况下工作,从而使您的代码更加自我记录(以及更高效,并且具有更好的自我解释能力)检查;如果您将 avrg=True 传递给它,干净的 Py3 代码将错误地通知您无法识别的参数,而 **kwargs 方法将需要显式检查未知参数,这会减慢您的速度并使代码膨胀.

最接近 Py3 错误检查的最小开销和类似 correctness/readability 是:

def get_event_stats(elengths, einds, *args, **kwargs):
    master_list = []
    # Unpack the recognized arguments (with default values), so kwargs left should be empty
    avg = kwargs.pop('avg', False)
    tot = kwargs.pop('tot', False)

    # If any keywords left over, they're unrecognized, raise an error
    if kwargs:
        # Arbitrarily select alphabetically first unknown keyword arg
        raise TypeError('get_event_stats() got an unexpected keyword argument {!r}'.format(min(kwargs)))

    if avg:
        for arg in args:
             do stuff...
    if tot:
        for arg in args:
             do stuff...

    return master_list