này tốt nhất có thể được minh họa bằng ví dụ (tất cả các ví dụ giả ast
được nhập khẩu; lưu ý rằng tôi đang sử dụng Python 2.7.1):Tại sao Python chèn Không vào các bước cắt?
# 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)
Vì vậy, như chúng ta có thể thấy, l[1:10]
kết quả trong một nút AST có lát có hai con - lower
và upper
cả hai được đặt thành chữ số - và con thứ ba trống là số step
. Nhưng [1:10:]
, mà chúng ta sẽ nghĩ là giống hệt nhau, đặt con của nó là step
của slice là biểu thức nghĩa đen().
Được rồi, tôi nghĩ vậy. Có thể Python xử lý l[1:10:]
và l[1:10]
là các loại biểu thức hoàn toàn khác nhau. Tham chiếu biểu thức Python (link) chắc chắn dường như chỉ ra như vậy; l[1:10]
là một lát cắt đơn giản, nhưng l[1:10:]
là một lát cắt mở rộng (chỉ với một lát cắt).
Nhưng, ngay cả trong bối cảnh cắt lát mở rộng, đối số bước được xử lý đặc biệt. Nếu chúng ta cố gắng phớt lờ phía trên hoặc thấp hơn bị ràng buộc trong một lát mở rộng với một mục lát, chúng tôi chỉ kết thúc với con trống:
# 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)
Hơn nữa, sau khi kiểm tra hơn nữa AST không thậm chí đối xử với những slicings như slicings mở rộng . Đây là những gì mở rộng slicings thực sự trông giống như:
# 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)
Vì vậy, đây là kết luận của tôi: AST luôn đối xử với các step
tham số đặc biệt đối với một số lý do, và unrelatedly, nút Slice
AST đại diện cho một lát dài (tôi đoán vậy có don không phải là hai lớp cơ sở khác nhau Slice
— ShortSlice
và LongSlice
- mặc dù tôi nghĩ rằng nó sẽ được ưa thích hơn) và do đó, một lát mở rộng một mục có thể được biểu diễn dưới dạng nút bình thường Slice
và được thực hiện như vậy vì một số lý do. Nó chỉ có vẻ sai với tôi để cho phép các thông số None
được hiểu là mặc định, nhưng tôi hiểu rằng đó là một quyết định thiết kế có mục đích; việc chèn None
bằng chữ và xử lý các lát dài như các nút Slice
dường như giống như tai nạn (hoặc các hiện vật thiết kế cũ).
Có ai khác có giải thích thông tin hơn không?