5

重複の可能性:
組み込みの範囲関数はどのようにして1つまたは3つの引数を取ることができますか?

の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(2つまたは3つの引数の署名を持つ2番目の引数)。

Pythonには関数のオーバーロードが存在しないため、可変数の引数を許可する一般的な方法はNone、デフォルト値として使用することです。たとえば、上記の動作を再現する1つの試みは次のようになります。

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 に答える