现在我有了上面的源代码:
class Stats(object):
def __init__(self):
self._pending = []
self._done = []
@property
def pending(self):
return self._pending这些清单的填写方式对我的问题并不重要。
情况是这样,我得到了这些列表的子列表:
stats = Stats()
// code to fill the lists
stats.pending[2:10]这里的问题是,我希望得到的元素和我检索的一样多。在上面的例子中,我期望一个包含8个元素(10-2)的子列表。
当然,如果列表较短,实际上我将得到少于8个元素。
所以,我需要的是:
这样,如果我这么做的话:
pending_tasks = stats.pending[44:46]挂起的列表只包含30个元素,它应该返回一个包含两个默认元素的列表,例如: None,None;而不是一个空list ([]),它是列表的默认行为。
我想我已经知道如何在一个正常的方法/函数中完成它了,但是我想以最干净的方式来完成它,如果可能的话,尝试遵循@property方法。
非常感谢!
发布于 2017-02-16 18:17:40
这不是一件容易的事情,因为切片操作是您想要修改的,这是在property返回原始列表之后发生的。不过,这并不是不可能的,您只需要用另一个对象包装常规列表,该对象负责为您填充切片。这将有多容易或有多难,这可能取决于您需要包装器实现的列表接口的多少。如果您只需要索引和切片,那么非常简单:
class PadSlice(object):
def __init__(self, lst, default_value=None):
self.lst = lst
self.default_value
def __getitem__(self, index):
item = getitem(self.lst, index)
if isinstance(index, slice):
expected_length = (index.stop - index.start) // (index.step or 1)
if len(item) != expected_length:
item.extend([default_value] * (expected_length - len(item)))
return item对于负步骤切片,或者不指定一个端点的片,这段代码可能无法正常工作(它有检测省略步骤的逻辑,因为这很常见)。如果这对你来说很重要的话,你也许可以把这些角落的箱子修好。
发布于 2017-02-16 18:17:51
这可不容易。您返回的对象(列表)如何知道它以后将如何被切片?但是,您可以子类list,并重写__getitem__和__getslice__ (仅限Python2):
class L(list):
def __getitem__(self, key):
if isinstance(key, slice):
return [list(self)[i] if 0 <= i < len(self) else None for i in xrange(key.start, key.stop, key.step or 1)]
return list(self)[key]
def __getslice__(self, i, j):
return self.__getitem__(slice(i, j))这将衬垫所有的切片与None,完全兼容负索引和步骤!= 1。在您的属性中,返回实际列表的L版本:
@property
def pending(self):
return L(self._pending)发布于 2017-02-16 18:44:01
您可以构造一个新类,它是list的一个子类。然后,您可以将__getitem__魔术方法重载到将[]操作符重载到适当的行为。假设list的这个子类称为MyList
class MyList(list):
def __getitem__(self, index):
"""Modify index [] operator"""
result = super(MyList, self).__getitem__(index)
if isinstance(index, slice):
# Get sublist length.
if index.step: # Check for zero to avoid divide by zero error
sublist_len = (index.stop - index.start) // index.step
else:
sublist_len = (index.stop - index.start)
# If sublist length is greater (or list is shorter), then extend
# the list to length requested with default value of None
if sublist_len > len(self) or index.start > len(self):
result.extend([None for _ in range(sublist_len - len(result))])
return result然后,只需更改pending方法以返回MyList类型,而不是list。
class Stats(object):
@property
def pending(self):
return MyList(self._pending)希望这能帮上忙。
https://stackoverflow.com/questions/42281234
复制相似问题