5

可能重复:
内置范围函数如何接受一个或三个参数?

Python 文档slice()列出了以下方法签名:

切片停止
切片(开始,停止[,步骤])

以下是创建具有不同数量参数的切片对象的几个示例:

>>> slice(8)
slice(None, 8, None)
>>> slice(4, 8)
slice(4, 8, None)
>>> slice(4, 8, 2)
slice(4, 8, 2)

请注意,如果您slice()使用单个参数调用,则该参数将用作stop属性(具有两个或三个参数签名的第二个参数)。

由于 Python 中不存在函数重载,因此允许可变数量的参数的典型方法是None用作默认值,例如,重现上述行为的尝试如下:

class myslice(object):
    def __init__(self, start, stop=None, step=None):
        if stop is None and step is None:
            # only one argument was provided, so use first argument as self.stop
            self.start = None
            self.stop = start
        else:
            self.start = start
            self.stop = stop
        self.step = step

    def __repr__(self):
        return 'myslice({}, {}, {})'.format(self.start, self.stop, self.step)

但是,这假定这None不是可以提供的值stop,请注意我的实现和之间的以下行为差异slice()

>>> slice(1, None)
slice(1, None, None)
>>> myslice(1, None)
myslice(None, 1, None)

是否有其他值可以用来代替None表明该参数绝对没有提供?或者,除了默认参数值之外,还有其他方法可以实现此行为吗?

编辑:顺便说一句,在 CPython 中,slice()是在 C 中实现的

4

1 回答 1

11

有几种方法可以处理默认参数问题。 None是最常见的,但是当None它实际上是一个合理的值时,您可以创建一个sentinel

sentinel = object()
def func(arg=sentinel):
    if arg is sentinel:
       arg = "default"
    do_code()

这是一个相关的答案,其中有一些关于使用Ellipsis作为哨兵的讨论,...也是单例。


另一种方法是使用*args和解包:

def func(*args):
   if len(args) == 3:
       start,stop,step=args
   elif len(args) == 2:
       start,stop = args
       step = None
   elif len(args) == 1:
       stop, = args  #Need the comma here.  Could write `stop = args[0]` instead ...
       step = start = None
   else:
       raise TypeError("Wrong number of arguments!")
于 2012-11-29T19:12:20.070 回答