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

为什么Python在切片步骤中插入None?,python,abstract-syntax-tree,Python,Abstract Syntax Tree,最好通过示例来说明这一点(所有示例都假设导入了ast;请注意,我使用的是Python 2.7.1): 因此,正如我们所看到的,l[1:10]产生一个AST节点,该节点的切片有两个子节点-lower和upper都设置为数值文本,第三个子节点为空step子节点。但是,我们认为相同的[1:10://code>,将其切片的步骤子级设置为无文本表达式(名称(id='None',ctx=Load())) 好吧,我想。也许Python将l[1:10://code>和l[1:10]视为完全不同的表达式。Pyth

最好通过示例来说明这一点(所有示例都假设导入了
ast
;请注意,我使用的是Python 2.7.1):

因此,正如我们所看到的,
l[1:10]
产生一个AST节点,该节点的切片有两个子节点-
lower
upper
都设置为数值文本,第三个子节点为空
step
子节点。但是,我们认为相同的
[1:10://code>,将其切片的
步骤
子级设置为
文本表达式(
名称(id='None',ctx=Load())

好吧,我想。也许Python将
l[1:10://code>和
l[1:10]
视为完全不同的表达式。Python表达式引用()显然表明了这一点
l[1:10]
是一个简单的切片,但是
l[1:10:
是一个扩展切片(只有一个切片项)

但是,即使在扩展切片的上下文中,步骤参数也会得到特殊处理。如果我们尝试忽略一个切片项目的扩展切片中的上限或下限,我们只会得到空的子项:

# 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甚至没有将这些滑动视为延伸滑动。下面是扩展滑轨的实际外观:

# 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)
因此,我的结论是:
step
参数总是因为某种原因而被认为是特殊的,
Slice
AST节点代表一个长切片(我想不必有两个不同的基本
切片
类-
短切片
长切片
——尽管我认为这是首选)因此,单个项目扩展切片可以表示为一个正常的
切片
节点,这样做是出于某种原因。我认为允许
None
参数解释为默认值是错误的,但我理解这是一个有目的的设计决策;
None
文本插入并将长切片视为默认值<代码>切片
节点看起来有点像意外事件(或旧设计的工件)


其他人有更明智的解释吗?

如果没有扩展切片表示法中的这种处理,您将无法区分
l[1:][/code>和
l[1:]
,您无法调用不同的特殊方法-
\uuuuu getslice\uuuu
可以为普通切片调用,但必须为扩展切片调用
\uuuuuuu getitem\uuuu

因此,它主要是Python 2.x的向后兼容性,在Python 3.x中已经消失了:

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)'
>>> 
有关更多信息,请参阅和

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)'
>>>