2011-12-09 11 views
5

Bu en iyi (tüm örnekler ast ithal edilir varsayalım; Python 2.7.1 kullanıyorum unutmayın) örnek gösterilebilir:Python neden hiçbiri dilim adımlarına ekler?

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

Yani, biz görebileceğiniz gibi, l[1:10] sonuçları olan dilim bir AST düğümünde iki çocuğa sahiptir: lower ve upper her ikisi de sayısal hazır bilgi olarak ayarlanır ve boş bir üçüncü step alt öğesi. Ancak aynı düşünebileceğimiz [1:10:], diliminin step çocuğunu None literal ifadesi() olarak ayarlar.

Tamam, düşündüm. Belki Python, l[1:10:] ve l[1:10]'u tamamen farklı tür ifadeler olarak ele alır. Python ifade referansı (link) kesinlikle böyle görünüyordu; l[1:10] basit bir dilimlemedir, ancak l[1:10:] genişletilmiş bir dilimlemedir (yalnızca bir dilim öğesiyle). Ancak, genişletilmiş dilimleme bağlamında bile, adım argümanı özel olarak işlem görür. biz üst veya bir dilim öğesiyle genişletilmiş dilimleme alt sınır görmezden çalışırsak, sadece boş çocuklu sonuna kadar:

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

Üstelik ek araştırmalarımız sonucunda AST olsa bile uzun dograma olarak bu doğramalar tedavi etmez . İşte doğramalar aslında benziyor genişletilmiş budur: Yani burada

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

benim sonuç şudur: AST hep unrelatedly nedense step parametre özel davranır ve, Slice AST düğümü uzun dilim (Öyle orada don tahmin temsil ve ShortSlice ve LongSlice sınıfları olmak üzere iki farklı baz olmalı - tercih edileni düşünmekteyim) ve böylece tek öğeli bir genişletilmiş dilim normal bir Slice düğüm olarak gösterilebilir ve bazı nedenlerden dolayı yapılır. None parametrelerinin varsayılan olarak yorumlanmasına izin vermek bana yanlış geliyor, ama bunun amaca yönelik bir tasarım kararı olduğunu anlıyorum; None'un uzun dilleri Slice düğümleri olarak eklemesi ve işlemden geçirilmesi, benzer kazalara (veya eski tasarımların eserler) benziyor.

Başka kimsenin daha bilinçli bir açıklaması var mı? genişletilmiş dilim gösterimde böyle Tedavi edilmezse

cevap

3

Eğer l[1:] ve l[1::] ayırt etmek mümkün olmaz ve farklı özel yöntemleri çağırmak olamazdı - __getslice__ normal dilim için çağrılan, ancak __getitem__ bir için çağrılması gerekir genişletilmiş dilim.

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

fazla bilgi için python2.7 source for ast.c ve data model description bakınız:

yüzden çoğunlukla Python 3.x kayboldu Python 2.x için bir geriye dönük uyumluluk şey.