首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Python在切片步骤中插入None?

为什么Python在切片步骤中插入None?
EN

Stack Overflow用户
提问于 2011-12-09 10:15:03
回答 1查看 398关注 0票数 5

这可以通过示例进行最好的说明(所有示例都假设导入了ast;请注意,我使用的是Python2.7.1):

代码语言:javascript
复制
# Outputs: Slice(lower=Num(n=1), upper=Num(n=10), step=None)
ast.dump(ast.parse("l[1:10]").body[0].value.slice)

# Outputs: Slice(lower=Num(n=1), upper=Num(n=10), step=Name(id='None', ctx=Load()))
ast.dump(ast.parse("l[1:10:]").body[0].value.slice)

# Outputs: Slice(lower=Num(n=1), upper=None, step=None)
ast.dump(ast.parse("l[1:]").body[0].value.slice)

# Outputs: Slice(lower=None, upper=None, step=None)
ast.dump(ast.parse("l[:]").body[0].value.slice)

因此,正如我们所看到的,l[1:10]产生了一个AST节点,它的切片有两个子节点--lowerupper都设置为数字字面值--以及一个空的第三个step子节点。但是,我们认为完全相同的[1:10:]将其切片的step子级设置为None文字表达式(Name(id='None', ctx=Load()))。

好吧,我想。也许Python将l[1:10:]l[1:10]视为完全不同类型的表达式。l[1:10]表达式参考(link)显然表明了这一点;Python是一个简单的切片,但l[1:10:]是一个扩展切片(只有一个切片项)。

但是,即使在扩展切片的上下文中,步骤参数也是特殊对待的。如果我们尝试忽略带有一个切片项的扩展切片中的上界或下界,我们最终只会得到空子对象:

代码语言:javascript
复制
# Outputs: Slice(lower=Num(n=1), upper=None, step=Name(id='None', ctx=Load()))
ast.dump(ast.parse("l[1::]").body[0].value.slice)

# Outputs: Slice(lower=None, upper=Num(n=10), step=Name(id='None', ctx=Load()))
ast.dump(ast.parse("l[:10:]").body[0].value.slice)

此外,在进一步检查时,AST甚至不会将这些切片视为扩展切片。下面是扩展切片的实际外观:

代码语言:javascript
复制
# Outputs: ExtSlice(dims=[Slice(lower=None, upper=None, step=Name(id='None', ctx=Load())), Slice(lower=None, upper=None, step=Name(id='None', ctx=Load()))])
ast.dump(ast.parse("l[::, ::]").body[0].value.slice)

因此,我的结论是:由于某些原因,AST总是特殊地对待step参数,而Slice AST节点表示一个很长的切片(我猜这样就不必有两个不同的Slice基类-ShortSliceLongSlice-though,我认为这会更好),因此单项扩展切片可以表示为普通的Slice节点,并且出于某种原因这样做。在我看来,允许将None参数解释为默认值似乎是错误的,但我理解这是一个有目的的设计决策;None文字插入并将长片段视为Slice节点看起来有点像是意外(或旧设计的工件)。

还有没有人有更明智的解释?

EN

回答 1

Stack Overflow用户

发布于 2011-12-09 21:50:46

如果在扩展切片表示法中没有这样的处理,您将无法区分l[1:]l[1::],并且无法调用不同的特殊方法-可以为普通切片调用__getslice__,但必须为扩展切片调用__getitem__

所以这主要是Python 2.x的向后兼容性问题,在Python 3.x中已经消失了:

代码语言:javascript
复制
Python 3.2 (r32:88445, Mar 25 2011, 19:28:28) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ast
>>> ast.dump(ast.parse("l[1:]").body[0].value.slice)
'Slice(lower=Num(n=1), upper=None, step=None)'
>>> ast.dump(ast.parse("l[1::]").body[0].value.slice)
'Slice(lower=Num(n=1), upper=None, step=None)'
>>> 

有关详细信息,请参阅python2.7 source for ast.cdata model description

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8440248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档