限制函数/方法的可选位置参数数量

2 投票
6 回答
1507 浏览
提问于 2025-04-15 15:54

如何限制一个函数或方法接受的可选位置参数的数量呢?比如,我想要一个函数,它可以接受两个或三个位置参数(但不能更多)。我不能使用可选的关键字参数,因为这个函数需要能够接受任意数量的命名关键字参数。到目前为止,我想到的解决办法是这样的:

def foo(x, y, *args, **kwargs):
    if len(args) == 1:
        # do something
    elif len(args) > 1:
        raise TypeError, "foo expected at most 3 arguments, got %d" % (len(args) + 2)
    else
        # do something else

这样做合理吗?还是有更好的方法呢?

6 个回答

1

你可以写一个装饰器:

class TooManyArgumentsException(Exception):
    pass

def limit_args(n):
    def limit_decorator(f):
        def new_f(*args, **kwargs):
            if len(args) > n:
                raise TooManyArgumentsException("%d args accepted at most, %d args passed" % (n, len(args)))
            return f(*args, **kwargs)
        return new_f
    return limit_decorator

然后可以这样使用它:

>>> @limit_args(5)
... def f(a, b, *args):
...     return a + b + sum(args)
...
>>> f(1, 2, 3)
6
>>> f(1, 2, 3, 4)
10
>>> f(1, 2, 3, 4, 5)
15
>>> f(1, 2, 3, 4, 5, 6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "limit.py", line 8, in new_f
    raise TooManyArgumentsException("%d args accepted at most, %d args passed" % (n, len(args)))
limit.TooManyArgumentsException: 5 args accepted at most, 6 args passed
>>> 
2

想要了解什么是“Pythonic”的一种方法,就是直接去看Python的源代码里面的例子。

find '/usr/lib/python2.6' -name '*.py' -exec egrep 'len\(args\)' {} + | wc
    156     867   12946

如果你仔细查看上面命令的结果(不加wc),你会发现很多地方都用到了你提到的那种技巧。

2

这个可以用:

>>> def foo(a, b, c=3, **kwargs):
    print(a, b, c, kwargs)


>>> foo(3, 4, 2)
3 4 2 {}
>>> foo(3, 4)
3 4 3 {}

撰写回答