繁体   English   中英

功能不承认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(这些只是int的数组)。 我试图通过传递一个可变长度的数组列表作为* 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应该作为关键字args传入,比如你的例子get_event_stats(..., avg=True, tot=False)那么它们就会填入kwargs 您可以使用键查找在kwargs dict中查找它们(如kwargs['avg']

但是如果它们根本不存在,则会产生一个关键错误,所以将它与dict.get()方法一起使用: kwargs.get('avg')如果不存在则返回None ,这是boolean 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:或者检查存在性和“真实性”,所以传递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

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

最接近Py3错误检查的最小开销和类似的正确性/可读性将是:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM