我有一个类跟踪搜索操作中遇到的错误
class SearchError(object):
def __init__(self,severity=0,message=''):
self.severity = severity
self.message = message
我的想法是让实例变量可转换。
所以,如果我有
a=SearchError(1,"Fatal Error")
我得到了
>>> a[0]
1
>>> a[1]
'Fatal Error'
>>> a.severity
1
>>> a.message
'Fatal Error'
为此,我在课程中添加了__getitem__
方法。现在班级变成了
class SearchError(object):
def __init__(self,severity=0,message=''):
self.severity = severity
self.message = message
def __getitem__(self,val):
if isinstance(val,slice):
return [self.__getitem__(i) for i in xrange(val.start,val.stop,val.step)]
elif val==0:
return self.severity
elif val==1:
return self.message
else:
raise IndexError
这是我想要的,但在
等情况下失败了>>> a[:2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 23, in __getitem__
TypeError: an integer is required
甚至
>>> a[-1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 29, in __getitem__
IndexError
我理解__getitem__
的实施是有限的。我需要知道的是 -
答案 0 :(得分:1)
这可以做到一切:
>>> from collections import namedtuple
>>> _SearchError = namedtuple("SearchError", "severity message")
>>> def SearchError(severity=0, message=''):
return _SearchError(severity, message)
答案 1 :(得分:1)
此处的问题是slice
个对象默认具有None
个值作为属性。因此,a[:2]
传入slice(None,2,None)
。如果您将其拆分并尝试将其传递给xrange
,您将获得TypeError
:
>>> xrange(None,2,None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required
试试a[0:2:1]
,您的代码就可以了。最终,你可以做类似的事情:
val.start = 0 if val.start is None else val.start
val.stop = 2 if val.stop is None else val.stop
val.stop = 2-val.stop if val.stop < 0 else val.stop
val.step = 1 if val.step is None else val.step
将您的切片解析为可用的索引(在一般情况下,最好使用len(self)
而不是2
,但我不知道您的对象是否已定义{{1 }}
或者,甚至更好:
__len__
同样地,在你执行start,stop,step = val.indices(len(self))
的情况下,你没有传入切片,0或1,所以你点击了a[-1]
子句,你可以在那里提出{{1} }}
答案 2 :(得分:1)
xrange
要求其所有参数都是整数,但slice
个对象具有None
用于未指定的属性。
实施您所追求的目标的最佳方式是使用namedtuple
:
from collections import namedtuple
class SearchError(namedtuple('SearchError', 'severity message')):
def __new__(cls, severity=0, message=''):
return super(SearchError, cls).__new__(cls, severity, message)
答案 3 :(得分:0)
我修改了代码,发现了以下解决方案。
它使用列表但仅存储变量的名称 - 不是实际值。此外,它还提供方法add
以添加具有给定名称和值的新变量。新变量也是可索引的。 (我的班级不需要添加功能,但周围很好)
感谢@mgilson在这个方向上轻推我
class SearchError(object):
def __init__(self,severity=0,message=''):
self.severity = severity
self.message = message
self._length = 2
self._vars_list = ['severity','message',]
def __getitem__(self,val):
if isinstance(val,slice):
steps = val.indices(self._length)
return [self.__getitem__(i) for i in xrange(*steps)]
elif val < 0:
i = self._length + val
if i < 0:
raise IndexError,"Index Out of range for SearchError object"
else:
return self.__getitem__(i)
else:
try:
return getattr(self,self._vars_list[val])
except IndexError:
raise IndexError,"Index Out of range for SearchError object"
def add(self,var_name,value):
self._vars_list.append(var_name)
self._length += 1
setattr(self,var_name,value)
结果
>>> a=SearchError(1,"Fatal Error")
>>> a[-1]
'Fatal Error'
>>> a[-2]
1
>>> a[-3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 14, in __getitem__
IndexError: Index Out of range for SearchError object
>>> a[2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 21, in __getitem__
IndexError: Index Out of range for SearchError object
>>> a[1]
'Fatal Error'
>>> a[0]
1
>>> a[:]
[1, 'Fatal Error']
>>> a.add('new_severity',8)
>>> a[:]
[1, 'Fatal Error', 8]
>>> a[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 21, in __getitem__
IndexError: Index Out of range for SearchError object
>>> a[2]
8
>>> a.new_severity
8
>>> a[:3]
[1, 'Fatal Error', 8]
>>> a[:4]
[1, 'Fatal Error', 8]
>>> a[:2]
[1, 'Fatal Error']
据我所见,您需要列表(存储实际变量或其名称)。如果有人有更好的选择,请发布