在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)
,这将是整个结果列表。然而,在我的实际例子中,内部函数要复杂得多,如果我知道用户想要的切片,我可以大大简化计算。但是我希望用户不必多做额外的事情就可以提前告诉我切片。
答案 0 :(得分:12)
以下几行中的某些内容对您有用:
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
的实例。通过这样做,您将能够使用熟悉的方括号语法。
答案 1 :(得分: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来做得更好,但这是一般的想法。
答案 2 :(得分:2)
一种方法(对于简单切片)将使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..]