什么是pythonic/更快的方法来检查;“关键”;自定义uuu getitem_uuuu方法的参数是切片?
我有一个自定义序列类型。它本质上是一个列表加上一个布尔标志的包装器,我希望它模拟通常的不可变序列行为 我的问题是切片。我知道在Python3中实现它的方法是有一个什么是pythonic/更快的方法来检查;“关键”;自定义uuu getitem_uuuu方法的参数是切片?,python,slice,magic-methods,typechecking,Python,Slice,Magic Methods,Typechecking,我有一个自定义序列类型。它本质上是一个列表加上一个布尔标志的包装器,我希望它模拟通常的不可变序列行为 我的问题是切片。我知道在Python3中实现它的方法是有一个\uuu getitem\uuu(key)方法,如果%key是单个索引,则返回一个项;如果%key是切片对象,则返回一个切片序列。但是我应该如何区分这些案例呢 我基本上有两个假设 sliced_list = self.wrapped_list[key] if isinstance(key, slice): return MyCu
\uuu getitem\uuu(key)
方法,如果%key
是单个索引,则返回一个项;如果%key
是切片对象,则返回一个切片序列。但是我应该如何区分这些案例呢
我基本上有两个假设
sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list
但这是邪恶的,不是吗?或
sliced_list = self.wrapped_list[key]
try:
return MyCustomSequenceType(sliced_list, boolean_flag)
except TypeError:
return sliced_list
后者看起来更像蟒蛇。它依赖于这样一个事实,即MyCustomSequenceType.\uu init\uuuu(self,datas,flag)
调用len(datas),因此如果%datas
是整数,则会引发TypeError
。但是,如果\uuuu init\uuuu
为另一个随机问题引发TypeError
,它将无法跟踪。还提示isinstance
更快(实际上更容易优化)
那我该怎么办呢?那应该是isinstance(key,slice)
,而不是isinstance(key,slice)
另外,您不应该直接调用\uuu getitem\uuu
——使用[]
项目符号
对于我自己来说,如果我需要辨别的话,我会使用isinstance(key,slice)
方法-slice
是一种非常特殊的东西,而不是很容易被其他类型替换的东西(想想看,如果self.wrapped_list
是列表
,那么切片
是返回元素或错误以外的唯一对象类型)
所以我会这样结束:
sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list
进一步考虑一下,你是否需要专门处理切片,我不知道你的情况是什么,但是当做出一个对以后会有影响的建筑决策时,通常考虑一种好的方法,考虑做同一件事情的几种不同的方法,并对它们进行评估并决定最好的方法。(并不是说我自己做的太多-我倾向于匆忙进入,然后实施并修补…。
您可以查看标准库并复制在那里完成的操作。例如,calendar.py具有:
def __getitem__(self, i):
funcs = self._months[i]
if isinstance(i, slice):
return [f(self.format) for f in funcs]
else:
return funcs(self.format)
它显示了使用isinstance进行显式检查,以及通过简单地将索引或切片传递到底层列表来部分回避问题。我认为使用\uuuu getitem\uuuuuu
是有意义的,因为使用标准列表
并不意味着具有限制性,当然,任何实现它也支持括号表示法,你是对的。如果%key
是一个切片,而wrapped\u list
只是一个索引,那么需要返回MyCustomSequenceType
的一个实例,就需要专门处理切片。我想不出更好的方法。无论如何,谢谢。Java开发人员我称赞这个解决方案的类型导向性。我还将问题编辑为isinstance(键,切片)
为了避免混淆潜在读者,让他们犯同样的错误。确实很明显。好吧,我还不习惯Python stdlib组织。下次我会仔细看看。谢谢。但我宁愿跳过else:
语句。如果是instance(I,slice)
bumpedTrue
,第一个return
语句已经出现,第二个语句将无法到达。我认为在这种情况下,isinstance
不是邪恶的。它有足够的非邪恶用途,可以包含在Python中(与goto不同),这可能是其中之一。好吧,它把我变成了蝾螈。好吧,我想那是邪恶的。除非你做了什么值得做的事。