5

假设我想写一个类似于range的函数

回想一下 range 有一个参数和 2/3 参数形式:

class range(object)
 |  range(stop) -> range object
 |  range(start, stop[, step]) -> range object

如果我希望方法或函数具有相同的接口,有没有比这更优雅的方法:

def range_like(*args):
    start,stop,step=[None]*3
    if len(args)==1:
        stop=args[0]
    elif len(args)==2:
        start,stop=args
    elif len(args)==3:
        start,stop,step=args
    else:
        raise ValueError       
    print(start,stop,step)
4

3 回答 3

5

这里没有太多建议,但一种替代方法是使用可选参数,如果只提供一个参数,则交换前两个:

def range_like(start, stop=None, step=1):
    if stop is None:
        start, stop = 0, start
    ...
于 2013-06-17T19:48:10.907 回答
4

我会把它写成:

def range_like(start=None, stop=None, step=1):
    if stop is None:
        start, stop = stop, start
    ...

如果那是你想要的?

[更新]您还可以添加:

    if stop is start is None:
        raise ValueError()

另外,使用哨兵对象而不是 None (这在 Python 中是不正常的,但你有时会看到):

NOTSET = object()
def range_like(start=NOTSET, stop=NOTSET, step=1):
    if stop is NOTSET:
        start, stop = stop, start

这允许None作为一个论点。

于 2013-06-17T19:47:42.633 回答
2

您不能使可选参数出现在强制参数之前。

您可以设计解决方法,例如交换参数:

def range_like(s, t=None, u=None):
    if t is None: 
        s,t = t,s
于 2013-06-17T19:49:43.797 回答