2011-12-09 8 views
5

これが最良の(すべての例はastがインポートされると仮定し、私は、Python 2.7.1を使用していますことに注意してください)の例で説明することができる。なぜPythonはスライスステップにNoneを挿入しますか?

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

だから、私たちが見ることができるように、スライスASTノードでl[1:10]結果lowerupperの両方が数値リテラルに設定され、空の第3子がstepの子になります。しかし、[1:10:]は、スライスのstep子がNoneのリテラル式()になるように設定します。

さて、私は考えました。多分、Pythonは全く異なる種類の式としてl[1:10:]l[1:10]を扱います。 Pythonの式参照(link)は確かにそうであるように思われました。 l[1:10]は単純なスライスですが、l[1:10:]は拡張スライス(1つのスライスアイテムのみ)です。

しかし、拡張スライスのコンテキストでも、step引数は特別に扱われます。私たちは、上または1つのスライス項目に拡張スライスで下限を無視しようとすると、私たちは、空の子供で終わる:

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

は私の結論です:ASTは常に何らかの理由で特別なstepパラメータを扱い、、unrelatedly、Slice ASTノードは、(私はそこにドンを推測長いスライスを表し、私はそれが望ましいだろうと思うが)SliceクラスShortSliceLongSliceである必要があります。したがって、単一アイテムの拡張スライスは通常のSliceノードとして表現でき、なんらかの理由で実行されます。 Noneのパラメータをデフォルトとして解釈させることは間違っているようですが、それは意図的な設計上の決定だったことを理解しています。 Noneリテラル挿入と長いスライスをSliceノードとして扱うことは、事故(または古いデザインのアーティファクト)のように見えるだけです。

もっと詳しい情報が他にありますか?拡張スライス表記で、このような処置がなければ

答えて

3

あなたはl[1:]l[1::]を区別することはできないだろう、とあなたは別の特別なメソッドを呼び出すことができませんでした - __getslice__は、通常のスライスのために呼び出すことができますが、__getitem__がために呼び出す必要があります拡張スライス。

だから、ほとんどのPython 3.xの中で消えてしまったのPython 2.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)' 
>>> 

は、より多くの情報のためpython2.7 source for ast.cdata model descriptionを参照してください。

関連する問題