2011-12-09 1 views
5

이것은, (모든 예 ast가 가져온 가정, 나는 파이썬 2.7.1를 사용하고 있습니다) 예에 의해 설명 될 수있다 :왜 파이썬은 슬라이스 단계에 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) 

그래서, 우리가 볼 수 있듯이, l[1:10] 결과를 그 조각 AST 노드에 lowerupper은 모두 숫자 리터럴로 설정되고 두 번째 자식은 step 인 자식이 두 개 있습니다. 그러나 [1:10:]은 동일하다고 생각하지만 슬라이스의 step 자식을 None 리터럴 표현식()으로 설정합니다.

좋습니다. 어쩌면 파이썬은 l[1:10:]l[1:10]을 완전히 다른 종류의 표현으로 취급합니다. 파이썬 표현식 참조 (link)는 분명히 그렇게 보였다. l[1:10]은 간단한 조각이지만, l[1:10:]은 확장 슬라이스 (슬라이스 항목이 하나만 있음)입니다.

그러나 확장 슬라이스의 경우에도 step 인수는 특별히 처리됩니다. 우리는 위 또는 한 조각의 항목을 확장 슬라이스의 하한을 무시하려고하면, 우리는 단지 빈 아이들과 함께 결국 :

# 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도 확장 slicings 이러한 slicings을 취급하지 않습니다 . 여기 slicings 실제로 같이 확장 작업은 다음과 같습니다 그래서 여기

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

나의 결론이다 : 대서양 표준시는 항상 unrelatedly, 어떤 이유로 step 매개 변수를 특별 취급 그리고, Slice AST 노드가 긴 조각 (내가 지금이 돈을 생각을 나타냅니다 Slice 클래스 - ShortSliceLongSlice - 두 개가 기본이되어야 함) - 따라서 단일 항목 확장 슬라이스는 보통 Slice 노드로 표시 될 수 있으며 어떤 이유로 든 수행됩니다. None 매개 변수가 기본값으로 해석되도록 허용하는 것은 나에게 잘못된 것처럼 보이지만, 이는 의도적 인 디자인 결정 이었음을 이해합니다. None 리터럴 삽입 및 긴 조각을 Slice 노드로 처리하면 사고 (또는 오래된 디자인의 인공물)처럼 보입니다.

더 많은 정보를 얻은 사람이 있습니까? 확장 슬라이스 표기법과 같은 치료를하지 않으면

답변

3

당신이 l[1:]l[1::] 구별 할 수 없을 것입니다, 당신은 다른 특별한 메소드를 호출 할 수 없습니다 - __getslice__는 일반 슬라이스에 대해 호출 할 수 있지만, __getitem__가에 대해 호출해야 확장 슬라이스.

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.x의에서 사라졌다 파이썬 2.x를위한 이전 버전과의 호환성 것입니다.