20

Pythonでは、一般的なスライス構文を正確にカプセル化して渡すことは可能ですか?sliceスライスを使用または__slice__エミュレートできることを知っています。ただし、で使用される角かっこに入れるのとまったく同じ構文を渡したいと思います__getitem__

たとえば、リストの一部を返す関数を作成したとします。

def get_important_values(some_list, some_condition, slice):
    elems = filter(some_condition, some_list)
    return elems[slice]

スライスオブジェクトを手動で渡すと、これは正常に機能します。

In [233]: get_important_values([1,2,3,4], lambda x: (x%2) == 0, slice(0, None))
Out[233]: [2, 4]

しかし、私がユーザーに渡させたいのは、ユーザーが使用したのとまったく同じスライス__getitem__です。

get_important_values([1,2,3,4], lambda x: (x%2) == 0, (0:-1) )

# or

get_important_values([1,2,3,4], lambda x: (x%2) == 0, (0:) )

明らかに、これは構文エラーを生成します。しかし、タイプスライス用に独自のミニパーサーを作成せずにx:y:t、ユーザーに文字列として渡すように強制することなく、これを機能させる方法はありますか?

動機

filter(some_condition, some_list)このサンプル関数に、結果全体がリストになるなど、直接スライス可能なものを返すようにすることもできます。ただし、実際の例では、内部関数ははるかに複雑であり、ユーザーが必要とするスライスを事前に知っていれば、計算を大幅に簡略化できます。しかし、事前にスライスを教えてもらうために、ユーザーが余分なことをする必要がないようにしたいと思います。

4

3 に答える 3

15

おそらく、次の線に沿った何かがあなたのために働くでしょう:

class SliceMaker(object):
  def __getitem__(self, item):
    return item

make_slice = SliceMaker()

print make_slice[3]
print make_slice[0:]
print make_slice[:-1]
print make_slice[1:10:2,...]

make_slice[]のインスタンスを手動で作成する代わりに、を使用するという考え方ですslice。これを行うことにより、おなじみの角かっこ構文をすべての栄光で使用できるようになります。

于 2012-12-04T15:37:15.700 に答える
2

要するに、違います。[]この構文は、演算子のコンテキストでのみ有効です。タプルを入力として受け入れてから、そのタプルをに渡すことをお勧めしslice()ます。あるいは、get_important_values()スライス可能なオブジェクトとして実装されるように、実行していることを再設計することもできます。

たとえば、次のようなことができます。

class ImportantValueGetter(object):
    def __init__(self, some_list, some_condition):
        self.some_list = some_list
        self.some_condition = some_condition

    def __getitem__(self, key):
        # Here key could be an int or a slice; you can do some type checking if necessary
        return filter(self.some_condition, self.some_list)[key]

これをある種のコンテナABCに変えることで、おそらく1つ上手くいくことができますが、それが一般的な考え方です。

于 2012-12-04T15:34:21.430 に答える
1

1つの方法(単純なスライスの場合)は、slice引数をdictまたはintのいずれかにすることです。

すなわち

get_important_values([1, 2, 3, 4], lambda x: (x%2) == 0, {0: -1})

また

get_important_values([1, 2, 3, 4], lambda x: (x%2) == 0, 1)

その場合、構文はほぼ同じままになります。

ただし、これは機能しません。

some_list[0:6:10..]
于 2012-12-04T15:35:36.240 に答える