2. Phân tích từ vựng

Một chương trình Python được đọc bởi parser. Đầu vào của trình phân tích cú pháp là một luồng tokens, được tạo bởi lexical analyzer (còn được gọi là tokenizer). Chương này mô tả cách bộ phân tích từ vựng tạo ra các mã thông báo này.

Trình phân tích từ vựng xác định encoding của văn bản chương trình (UTF-8 theo mặc định) và giải mã văn bản thành source characters. Nếu không thể giải mã được văn bản, SyntaxError sẽ xuất hiện.

Tiếp theo, bộ phân tích từ vựng sử dụng các ký tự nguồn để tạo ra dòng mã thông báo. Loại mã thông báo được tạo thường phụ thuộc vào ký tự nguồn tiếp theo sẽ được xử lý. Tương tự, hành vi đặc biệt khác của máy phân tích phụ thuộc vào ký tự nguồn đầu tiên chưa được xử lý. Bảng sau đây cung cấp bản tóm tắt nhanh về các ký tự nguồn này, kèm theo các liên kết đến các phần chứa nhiều thông tin hơn.

nhân vật

Mã thông báo tiếp theo (hoặc tài liệu liên quan khác)

  • không gian

  • tab

  • thức ăn hình thành

  • CR, LF

  • dấu gạch chéo ngược (\)

  • hàm băm (#)

  • trích dẫn (', ")

  • thư ASCII (a-z, A-Z)

  • ký tự không phải ASCII

  • gạch dưới (_)

  • số (0-9)

  • dấu chấm (.)

  • dấu chấm hỏi (?)

  • đô la ($)

  • trích dẫn ngược (​`​)

  • ký tự điều khiển

  • Lỗi (chuỗi ký tự bên ngoài và nhận xét)

  • ký tự in khác

  • cuối tập tin

2.1. Cấu trúc đường

Một chương trình Python được chia thành một số logical lines.

2.1.1. Dòng logic

Sự kết thúc của một dòng logic được biểu thị bằng mã thông báo NEWLINE. Các câu lệnh không thể vượt qua ranh giới dòng logic trừ khi NEWLINE được cú pháp cho phép (ví dụ: giữa các câu lệnh trong câu lệnh ghép). Một dòng logic được xây dựng từ một hoặc nhiều physical lines bằng cách tuân theo các quy tắc explicit hoặc implicit line joining.

2.1.2. Đường vật lý

Một dòng vật lý là một chuỗi các ký tự được kết thúc bởi một trong các chuỗi cuối dòng sau:

  • dạng Unix sử dụng ASCII LF (nguồn cấp dữ liệu),

  • biểu mẫu Windows sử dụng chuỗi ASCII CR LF (trả về theo sau là nguồn cấp dữ liệu),

  • dạng 'Classic Mac OS' sử dụng ký tự ASCII CR (return).

Bất kể nền tảng nào, mỗi chuỗi này đều được thay thế bằng một ký tự ASCII LF (nguồn cấp dữ liệu) duy nhất. (Điều này được thực hiện ngay cả bên trong string literals.) Mỗi ​​dòng có thể sử dụng bất kỳ chuỗi nào; chúng không cần phải nhất quán trong một tập tin.

Phần cuối của đầu vào cũng đóng vai trò là điểm kết thúc ngầm cho dòng vật lý cuối cùng.

Chính thức:

newline: <ASCII LF> | <ASCII CR> <ASCII LF> | <ASCII CR>

2.1.3. Bình luận

Một nhận xét bắt đầu bằng ký tự băm (#) không phải là một phần của chuỗi ký tự và kết thúc ở cuối dòng vật lý. Một chú thích biểu thị sự kết thúc của dòng logic trừ khi các quy tắc nối dòng ẩn được gọi. Các bình luận bị bỏ qua theo cú pháp.

2.1.4. Khai báo mã hóa

Nếu nhận xét ở dòng đầu tiên hoặc dòng thứ hai của tập lệnh Python khớp với biểu thức chính quy coding[=:]\s*([-\w.]+) thì nhận xét này sẽ được xử lý dưới dạng khai báo mã hóa; nhóm đầu tiên của biểu thức này đặt tên cho mã hóa của tệp mã nguồn. Khai báo mã hóa phải xuất hiện trên một dòng riêng. Nếu là dòng thứ hai thì dòng đầu tiên cũng phải là dòng chỉ dành cho nhận xét. Các dạng biểu thức mã hóa được đề xuất là

# -zz000zz-

cũng được GNU Emacs công nhận và

# vim:fileencoding=<encoding-name>

được công nhận bởi VIM của Bram Moolenaar.

Nếu không tìm thấy khai báo mã hóa thì mã hóa mặc định là UTF-8. Nếu mã hóa ngầm định hoặc rõ ràng của tệp là UTF-8, thì dấu thứ tự byte UTF-8 ban đầu (b'\xef\xbb\xbf') sẽ bị bỏ qua chứ không phải là lỗi cú pháp.

Nếu một mã hóa được khai báo thì tên mã hóa phải được Python nhận dạng (xem Mã hóa tiêu chuẩn). Mã hóa được sử dụng cho tất cả các phân tích từ vựng, bao gồm cả chuỗi ký tự, nhận xét và mã định danh.

Tất cả phân tích từ vựng, bao gồm chuỗi ký tự, nhận xét và mã định danh, đều hoạt động trên văn bản Unicode được giải mã bằng cách sử dụng mã hóa nguồn. Bất kỳ điểm mã Unicode nào, ngoại trừ ký tự điều khiển NUL, đều có thể xuất hiện trong nguồn Python.

source_character:  <any Unicode code point, except NUL>

2.1.5. Nối dòng rõ ràng

Hai hoặc nhiều dòng vật lý có thể được nối thành các dòng logic bằng cách sử dụng các ký tự dấu gạch chéo ngược (\), như sau: khi một dòng vật lý kết thúc bằng dấu gạch chéo ngược không phải là một phần của chuỗi ký tự hoặc nhận xét, nó sẽ được nối với dòng sau để tạo thành một dòng logic duy nhất, xóa dấu gạch chéo ngược và ký tự cuối dòng tiếp theo. Ví dụ:

nếu 1900 < năm < 2100  1 <= tháng <= 12 \
    1 <= ngày <= 31  0 <= giờ < 24 \
    0 <= phút < 60  0 <= giây < 60: # Looks giống như một ngày hợp lệ
        trở lại 1

Một dòng kết thúc bằng dấu gạch chéo ngược không thể mang chú thích. Dấu gạch chéo ngược không tiếp tục nhận xét. Dấu gạch chéo ngược không tiếp tục mã thông báo ngoại trừ các chuỗi ký tự (nghĩa là các mã thông báo không phải là chuỗi ký tự không thể được phân chia thành các dòng vật lý bằng cách sử dụng dấu gạch chéo ngược). Dấu gạch chéo ngược là bất hợp pháp ở những nơi khác trên một dòng bên ngoài chuỗi ký tự.

2.1.6. Nối dòng ngầm định

Các biểu thức trong dấu ngoặc đơn, dấu ngoặc vuông hoặc dấu ngoặc nhọn có thể được phân tách trên nhiều dòng vật lý mà không cần sử dụng dấu gạch chéo ngược. Ví dụ:

tháng_names = ['Januari', 'Februari', 'Maart', # These là
               Tên 'Tháng Tư', 'Mei', 'Juni', # Dutch
               'Juli', 'Augustus', 'Tháng 9', # for các tháng
               'Tháng 10', 'Tháng 11', 'Tháng 12'] # of năm

Các dòng tiếp tục ngầm có thể mang ý kiến. Việc thụt lề của các dòng tiếp tục không quan trọng. Các dòng tiếp tục trống được cho phép. Không có mã thông báo NEWLINE giữa các dòng tiếp tục ngầm định. Các dòng tiếp tục ngầm cũng có thể xuất hiện trong các chuỗi có ba dấu ngoặc kép (xem bên dưới); trong trường hợp đó họ không thể mang theo ý kiến.

2.1.7. Dòng trống

Một dòng logic chỉ chứa dấu cách, tab, nguồn cấp dữ liệu biểu mẫu và có thể là nhận xét sẽ bị bỏ qua (tức là không có mã thông báo NEWLINE nào được tạo). Trong quá trình nhập câu lệnh tương tác, việc xử lý dòng trống có thể khác nhau tùy thuộc vào việc triển khai vòng lặp đọc-đánh giá-in. Trong trình thông dịch tương tác tiêu chuẩn, một dòng logic hoàn toàn trống (nghĩa là một dòng thậm chí không chứa khoảng trắng hoặc nhận xét) sẽ kết thúc một câu lệnh nhiều dòng.

2.1.8. Thụt lề

Khoảng trắng ở đầu (dấu cách và tab) ở đầu dòng logic được sử dụng để tính toán mức độ thụt lề của dòng, từ đó được sử dụng để xác định nhóm các câu lệnh.

Các tab được thay thế (từ trái sang phải) từ một đến tám khoảng trắng sao cho tổng số ký tự từ trên xuống và bao gồm cả phần thay thế là bội số của tám (điều này nhằm mục đích tương tự quy tắc được sử dụng bởi Unix). Tổng số khoảng trắng trước ký tự không trống đầu tiên sẽ xác định mức thụt dòng của dòng. Không thể phân chia thụt lề trên nhiều dòng vật lý bằng dấu gạch chéo ngược; khoảng trắng cho đến dấu gạch chéo ngược đầu tiên xác định mức thụt lề.

Việc thụt lề bị từ chối vì không nhất quán nếu tệp nguồn trộn lẫn các tab và dấu cách theo cách làm cho ý nghĩa phụ thuộc vào giá trị của tab trong dấu cách; một TabError được nêu ra trong trường hợp đó.

Cross-platform compatibility note: do tính chất của trình soạn thảo văn bản trên các nền tảng không phải UNIX, việc sử dụng kết hợp các khoảng trắng và tab để thụt lề trong một tệp nguồn duy nhất là không khôn ngoan. Cũng cần lưu ý rằng các nền tảng khác nhau có thể giới hạn rõ ràng mức thụt lề tối đa.

Ký tự nguồn cấp dữ liệu có thể xuất hiện ở đầu dòng; nó sẽ bị bỏ qua đối với các tính toán thụt đầu dòng ở trên. Các ký tự nguồn cấp dữ liệu xuất hiện ở nơi khác trong khoảng trắng ở đầu có hiệu ứng không xác định (ví dụ: chúng có thể đặt lại số lượng khoảng trắng về 0).

Mức độ thụt lề của các dòng liên tiếp được sử dụng để tạo mã thông báo INDENTDEDENT, sử dụng ngăn xếp như sau.

Trước khi dòng đầu tiên của tệp được đọc, một số 0 duy nhất được đẩy vào ngăn xếp; điều này sẽ không bao giờ được bật ra nữa. Các số được đẩy vào ngăn xếp sẽ luôn tăng dần từ dưới lên trên. Ở đầu mỗi dòng logic, mức độ thụt lề của dòng được so sánh với đỉnh của ngăn xếp. Nếu bằng nhau thì không có chuyện gì xảy ra. Nếu nó lớn hơn, nó sẽ được đẩy vào ngăn xếp và một mã thông báo INDENT sẽ được tạo. Nếu nó nhỏ hơn, thì must là một trong những số xuất hiện trên ngăn xếp; tất cả các số trên ngăn xếp lớn hơn sẽ được bật ra và với mỗi số được bật ra, mã thông báo DEDENT sẽ được tạo. Ở cuối tệp, mã thông báo DEDENT được tạo cho mỗi số còn lại trên ngăn xếp lớn hơn 0.

Đây là một ví dụ về một đoạn mã Python được thụt lề chính xác (mặc dù gây nhầm lẫn):

def perm(l):
        # Compute danh sách tất cả các hoán vị của l
    nếu len(l) <= 1:
                  trở lại [l]
    r = []
    cho tôi trong phạm vi(len(l)):
             s = l[:i] + l[i+1:]
             p = perm
             cho x trong p:
              r.append(l[i:i+1] + x)
    trả lại r

Ví dụ sau đây cho thấy nhiều lỗi thụt lề khác nhau:

def perm(l): # error: thụt lề dòng đầu tiên
cho i trong phạm vi(len(l)): # error: không thụt lề
    s = l[:i] + l[i+1:]
        p = perm(l[:i] + l[i+1:]) # error: thụt lề không mong muốn
        cho x trong p:
                r.append(l[i:i+1] + x)
            return r # error: thụt lề không nhất quán

(Trên thực tế, ba lỗi đầu tiên được trình phân tích cú pháp phát hiện; chỉ có lỗi cuối cùng được trình phân tích từ vựng tìm thấy --- mức thụt lề của return r không khớp với mức bật ra khỏi ngăn xếp.)

2.1.9. Khoảng trắng giữa các mã thông báo

Ngoại trừ ở đầu dòng logic hoặc trong chuỗi ký tự, khoảng trắng, tab và nguồn cấp dữ liệu biểu mẫu có thể được sử dụng thay thế cho nhau để phân tách các mã thông báo:

whitespace:  ' ' | tab | formfeed

Chỉ cần khoảng trắng giữa hai mã thông báo nếu cách nối của chúng có thể được hiểu là một mã thông báo khác. Ví dụ: ab là một mã thông báo, nhưng a b là hai mã thông báo. Tuy nhiên, +a+ a đều tạo ra hai mã thông báo, +a, vì +a không phải là mã thông báo hợp lệ.

2.1.10. Điểm đánh dấu cuối

Khi kết thúc đầu vào không tương tác, bộ phân tích từ vựng sẽ tạo mã thông báo ENDMARKER.

2.2. Token khác

Ngoài NEWLINE, INDENTDEDENT, còn tồn tại các loại mã thông báo sau: identifierskeywords (NAME), literals (chẳng hạn như NUMBERSTRING) và các ký hiệu khác (operatorsdelimiters, OP). Các ký tự khoảng trắng (trừ các dấu kết thúc dòng logic, đã thảo luận trước đó) không phải là mã thông báo mà dùng để phân cách các mã thông báo. Khi có sự mơ hồ, mã thông báo bao gồm chuỗi dài nhất có thể tạo thành mã thông báo hợp pháp khi đọc từ trái sang phải.

2.3. Tên (số nhận dạng và từ khóa)

Mã thông báo NAME đại diện cho identifiers, keywordssoft keywords.

Tên bao gồm các ký tự sau:

  • chữ hoa và chữ thường (A-Za-z),

  • dấu gạch dưới (_),

  • các chữ số (0 đến 9), không thể xuất hiện dưới dạng ký tự đầu tiên và

  • các ký tự không phải ASCII. Tên hợp lệ chỉ có thể chứa các ký tự "giống chữ cái" và "giống chữ số"; xem Các ký tự không phải ASCII trong tên để biết chi tiết.

Tên phải chứa ít nhất một ký tự nhưng không có giới hạn độ dài trên. Vụ án có ý nghĩa.

Về mặt hình thức, tên được mô tả theo các định nghĩa từ vựng sau:

NAME:          name_start name_continue*
name_start:    "a"..."z" | "A"..."Z" | "_" | <non-ASCII character>
name_continue: name_start | "0"..."9"
identifier:    <NAME, except keywords>

Lưu ý rằng không phải tất cả các tên khớp với ngữ pháp này đều hợp lệ; xem Các ký tự không phải ASCII trong tên để biết chi tiết.

2.3.1. Từ khóa

Các tên sau đây được sử dụng làm từ dành riêng hoặc keywords của ngôn ngữ và không thể được sử dụng làm số nhận dạng thông thường. Chúng phải được đánh vần chính xác như được viết ở đây:

Sai đang chờ thẻ nhập khác
Không nghỉ trừ khi tăng lương
Lớp học thực sự cuối cùng đã trở lại
và tiếp tục thử lambda
như def từ nonlocal while
khẳng định del toàn cầu không phải với
async Elif if hoặc mang lại

2.3.2. Từ khóa mềm

Added in version 3.10.

Một số tên chỉ được bảo lưu trong bối cảnh cụ thể. Chúng được gọi là soft keywords:

  • match, case_ khi được sử dụng trong câu lệnh match.

  • type, khi được sử dụng trong câu lệnh type.

Về mặt cú pháp, chúng hoạt động như từ khóa trong ngữ cảnh cụ thể của chúng, nhưng sự khác biệt này được thực hiện ở cấp trình phân tích cú pháp chứ không phải khi mã hóa.

Là từ khóa mềm, việc sử dụng chúng trong ngữ pháp là có thể trong khi vẫn duy trì khả năng tương thích với mã hiện có sử dụng các tên này làm tên định danh.

Thay đổi trong phiên bản 3.12: type hiện là một từ khóa mềm.

2.3.3. Các lớp định danh dành riêng

Một số loại định danh nhất định (ngoài từ khóa) có ý nghĩa đặc biệt. Các lớp này được xác định bằng các mẫu ký tự gạch dưới ở đầu và cuối:

_*

Không được nhập bởi from module import *.

_

Trong mẫu case trong câu lệnh match, _soft keyword biểu thị wildcard.

Riêng biệt, trình thông dịch tương tác cung cấp kết quả đánh giá cuối cùng trong biến _. (Nó được lưu trữ trong mô-đun builtins, cùng với các chức năng tích hợp sẵn như print.)

Ở những nơi khác, _ là số nhận dạng thông thường. Nó thường được dùng để đặt tên cho các mục "đặc biệt", nhưng nó không đặc biệt đối với bản thân Python.

Ghi chú

Tên _ thường được sử dụng cùng với quốc tế hóa; tham khảo tài liệu dành cho mô-đun gettext để biết thêm thông tin về quy ước này.

Nó cũng thường được sử dụng cho các biến không sử dụng.

__*__

Tên do hệ thống xác định, được gọi một cách không chính thức là tên "dunder". Những tên này được xác định bởi trình thông dịch và cách triển khai nó (bao gồm cả thư viện chuẩn). Tên hệ thống hiện tại được thảo luận trong phần Tên phương thức đặc biệt và những nơi khác. Nhiều khả năng sẽ được xác định trong các phiên bản tương lai của Python. Any việc sử dụng tên __*__, trong bất kỳ bối cảnh nào, không tuân theo việc sử dụng được ghi chép rõ ràng, có thể bị hỏng mà không có cảnh báo.

__*

Tên riêng của lớp. Các tên trong danh mục này, khi được sử dụng trong ngữ cảnh của định nghĩa lớp, sẽ được viết lại để sử dụng dạng đọc sai nhằm giúp tránh xung đột tên giữa các thuộc tính "riêng tư" của lớp cơ sở và lớp dẫn xuất. Xem phần Mã định danh (Tên).

2.3.4. Các ký tự không phải ASCII trong tên

Tên chứa các ký tự không phải là ASCII cần được chuẩn hóa và xác thực bổ sung ngoài các quy tắc và ngữ pháp được giải thích above. Ví dụ: ř_1, hoặc साँप là tên hợp lệ nhưng r〰2, hoặc 🐍 thì không.

Phần này giải thích các quy tắc chính xác.

Tất cả các tên được chuyển đổi thành normalization form NFKC trong khi phân tích cú pháp. Điều này có nghĩa là, chẳng hạn, một số biến thể kiểu chữ của các ký tự được chuyển đổi sang dạng "cơ bản" của chúng. Ví dụ: fiⁿₐˡᵢᶻₐᵗᵢᵒₙ chuẩn hóa thành finalization, vì vậy Python coi chúng có cùng tên:

>>> fiⁿₐˡᵢᶻₐᵗᵢᵒₙ = 3
>>> hoàn thiện
3

Ghi chú

Việc chuẩn hóa chỉ được thực hiện ở cấp độ từ vựng. Các hàm thời gian chạy có tên là strings thường không bình thường hóa các đối số của chúng. Ví dụ: biến được xác định ở trên có thể truy cập được trong thời gian chạy trong từ điển globals() dưới dạng globals()["finalization"] chứ không phải globals()["fiⁿₐˡᵢᶻₐᵗᵢᵒₙ"].

Tương tự như cách các tên chỉ dành cho ASCII chỉ được chứa các chữ cái, chữ số và dấu gạch dưới và không được bắt đầu bằng một chữ số, tên hợp lệ phải bắt đầu bằng một ký tự trong bộ "giống chữ cái" xid_start và các ký tự còn lại phải nằm trong bộ "giống chữ cái và chữ số" xid_continue.

Các bộ này dựa trên các bộ XID_StartXID_Continue như được xác định bởi phụ lục tiêu chuẩn Unicode UAX-31. xid_start của Python còn bao gồm cả dấu gạch dưới (_). Lưu ý rằng Python không nhất thiết phải tuân theo UAX-31.

Danh sách các ký tự không theo quy chuẩn trong bộ XID_StartXID_Continue như được định nghĩa bởi Unicode có sẵn trong tệp DerivedCoreProperties.txt trong Cơ sở dữ liệu ký tự Unicode. Để tham khảo, các quy tắc xây dựng cho bộ xid_* được đưa ra dưới đây.

Tập id_start được định nghĩa là hợp của:

  • Danh mục Unicode <Lu> - chữ in hoa (bao gồm A đến Z)

  • Danh mục Unicode <Ll> - chữ cái viết thường (bao gồm a đến z)

  • Danh mục Unicode <Lt> - chữ cái viết hoa tiêu đề

  • Danh mục Unicode <Lm> - chữ cái sửa đổi

  • Danh mục Unicode <Lo> - các chữ cái khác

  • Danh mục Unicode <Nl> - số chữ cái

  • {"_"} - dấu gạch dưới

  • <Other_ID_Start> - một bộ ký tự rõ ràng trong PropList.txt để hỗ trợ khả năng tương thích ngược

Sau đó, tập hợp xid_start sẽ đóng tập hợp này dưới chế độ chuẩn hóa NFKC, bằng cách loại bỏ tất cả các ký tự có chế độ chuẩn hóa không có dạng id_start id_continue*.

Tập id_continue được định nghĩa là hợp của:

  • id_start (xem ở trên)

  • Danh mục Unicode <Nd> - số thập phân (bao gồm 0 đến 9)

  • Danh mục Unicode <Pc> - dấu câu kết nối

  • Danh mục Unicode <Mn> - dấu không cách

  • Danh mục Unicode <Mc> - dấu cách kết hợp

  • <Other_ID_Continue> - một bộ ký tự rõ ràng khác trong PropList.txt để hỗ trợ khả năng tương thích ngược

Một lần nữa, xid_continue đóng tập hợp này dưới sự chuẩn hóa NFKC.

Các danh mục Unicode sử dụng phiên bản Cơ sở dữ liệu ký tự Unicode như được bao gồm trong mô-đun unicodedata.

Xem thêm

  • PEP 3131 -- Hỗ trợ số nhận dạng không phải ASCII

  • PEP 672 - Những cân nhắc về bảo mật liên quan đến Unicode cho Python

2.4. chữ

Literal là ký hiệu cho các giá trị không đổi của một số loại có sẵn.

Về mặt phân tích từ vựng, Python có các chữ string, bytesnumeric.

Các "chữ" khác được biểu thị bằng từ vựng bằng keywords (None, True, False) và ellipsis token đặc biệt (...).

2.5. Chuỗi và byte bằng chữ

Chuỗi ký tự là văn bản được đặt trong dấu ngoặc đơn (') hoặc dấu ngoặc kép ("). Ví dụ:

"thư rác"
'trứng'

Trích dẫn được sử dụng để bắt đầu bằng chữ cũng kết thúc nó, do đó, một chuỗi ký tự chỉ có thể chứa trích dẫn khác (ngoại trừ các chuỗi thoát, xem bên dưới). Ví dụ:

'Làm ơn nói "Xin chào" đi.'
"Đừng làm thế!"

Ngoại trừ giới hạn này, việc lựa chọn ký tự trích dẫn (' hoặc ") không ảnh hưởng đến cách phân tích cú pháp chữ.

Bên trong một chuỗi ký tự, ký tự dấu gạch chéo ngược (\) giới thiệu một escape sequence, có ý nghĩa đặc biệt tùy thuộc vào ký tự sau dấu gạch chéo ngược. Ví dụ: \" biểu thị ký tự trích dẫn kép và not có kết thúc chuỗi không:

>>> print("Nói \"Xin chào\" với mọi người!")
Hãy nói "Xin chào" với mọi người!

Xem escape sequences bên dưới để biết danh sách đầy đủ các trình tự như vậy và biết thêm chi tiết.

2.5.1. Chuỗi trích dẫn ba

Các chuỗi cũng có thể được đặt trong các nhóm phù hợp gồm ba dấu ngoặc đơn hoặc dấu ngoặc kép. Chúng thường được gọi là triple-quoted strings:

"""Đây là một chuỗi có ba dấu ngoặc kép."""

Trong các chữ có dấu ngoặc kép ba lần, các dấu ngoặc kép không thoát được cho phép (và được giữ lại), ngoại trừ ba dấu ngoặc kép không thoát liên tiếp sẽ chấm dứt chữ, nếu chúng cùng loại (' hoặc ") được sử dụng ở đầu:

"""Chuỗi này có "dấu ngoặc kép" bên trong."""

Các dòng mới không thoát cũng được cho phép và giữ lại:

'''Chuỗi ba trích dẫn này
tiếp tục ở dòng tiếp theo.'''

2.5.2. Tiền tố chuỗi

Ví dụ, các chuỗi ký tự có thể có một prefix tùy chọn ảnh hưởng đến cách phân tích nội dung của chuỗi ký tự, ví dụ:

b"dữ liệu"
f'{kết quả=}'

Các tiền tố được phép là:

Xem các phần được liên kết để biết chi tiết về từng loại.

Tiền tố không phân biệt chữ hoa chữ thường (ví dụ: 'B' hoạt động giống như 'b'). Tiền tố 'r' có thể được kết hợp với 'f', 't' hoặc 'b', vì vậy 'fr', 'rf', 'tr', 'rt', 'br' và 'rb' cũng là các tiền tố hợp lệ.

Added in version 3.3: Tiền tố 'rb' của các byte thô đã được thêm dưới dạng từ đồng nghĩa của 'br'.

Hỗ trợ cho chữ unicode kế thừa (u'value') đã được giới thiệu lại để đơn giản hóa việc bảo trì cơ sở mã Python 2.x và 3.x kép. Xem PEP 414 để biết thêm thông tin.

2.5.3. Ngữ pháp chính thức

Các chuỗi ký tự, ngoại trừ "f-strings""t-strings", được mô tả bằng các định nghĩa từ vựng sau đây.

Các định nghĩa này sử dụng negative lookaheads (!) để chỉ ra rằng một trích dẫn kết thúc theo nghĩa đen.

STRING:          [stringprefix] (stringcontent)
stringprefix:    <("r" | "u" | "b" | "br" | "rb"), case-insensitive>
stringcontent:
   | "'''" ( !"'''" longstringitem)* "'''"
   | '"""' ( !'"""' longstringitem)* '"""'
   | "'" ( !"'" stringitem)* "'"
   | '"' ( !'"' stringitem)* '"'
stringitem:      stringchar | stringescapeseq
stringchar:      <any source_character, except backslash and newline>
longstringitem:  stringitem | newline
stringescapeseq: "\" <any source_character>

Lưu ý rằng như trong tất cả các định nghĩa từ vựng, khoảng trắng rất quan trọng. Đặc biệt, tiền tố (nếu có) phải được đặt ngay sau dấu ngoặc kép bắt đầu.

2.5.4. Trình tự thoát

Trừ khi có tiền tố 'r' hoặc 'R', các chuỗi thoát ở dạng chuỗi và byte bằng chữ được diễn giải theo các quy tắc tương tự như các quy tắc được sử dụng bởi Tiêu chuẩn C. Các chuỗi thoát được công nhận là:

Trình tự thoát

Ý nghĩa

\<dòng mới>

Bỏ qua cuối dòng

\\

Backslash

\'

Single quote

\"

Double quote

\a

Chuông ASCII (BEL)

\b

ASCII Phím lùi (BS)

\f

Nguồn cấp dữ liệu biểu mẫu ASCII (FF)

\n

Nguồn cấp dữ liệu dòng ASCII (LF)

\r

ASCII Trả lại vận chuyển (CR)

\t

Tab ngang ASCII (TAB)

\v

Tab dọc ASCII (VT)

\ooo

Ký tự bát phân

\xhh

Ký tự thập lục phân

\N{name}

Ký tự Unicode được đặt tên

\uxxxx

Hexadecimal Unicode character

\Uxxxxxxxx

Hexadecimal Unicode character

2.5.4.1. Bỏ qua cuối dòng

Một dấu gạch chéo ngược có thể được thêm vào cuối dòng để bỏ qua dòng mới

>>> 'Chuỗi này sẽ không bao gồm \
... dấu gạch chéo ngược hoặc ký tự dòng mới.'
'Chuỗi này sẽ không bao gồm dấu gạch chéo ngược hoặc ký tự dòng mới.'

Có thể đạt được kết quả tương tự bằng cách sử dụng triple-quoted strings hoặc dấu ngoặc đơn và string literal concatenation.

2.5.4.2. Ký tự thoát

Để bao gồm dấu gạch chéo ngược trong chuỗi ký tự Python không phải raw, nó phải được nhân đôi. Chuỗi thoát \\ biểu thị một ký tự dấu gạch chéo ngược duy nhất:

>>> print('C:\\Program Files')
C:\Tệp chương trình

Tương tự, các chuỗi \'\" lần lượt biểu thị ký tự trích dẫn đơn và trích dẫn kép:

>>> in('\'\"')
' và "

2.5.4.3. Ký tự bát phân

Chuỗi \ooo biểu thị character với giá trị bát phân (cơ số 8) ooo:

>>> '\120'
'P'

Tối đa ba chữ số bát phân (0 đến 7) được chấp nhận.

Theo nghĩa đen, character có nghĩa là byte với giá trị đã cho. Trong một chuỗi ký tự, nó có nghĩa là một ký tự Unicode có giá trị đã cho.

Thay đổi trong phiên bản 3.11: Thoát bát phân có giá trị lớn hơn 0o377 (255) tạo ra DeprecationWarning.

Thay đổi trong phiên bản 3.12: Thoát bát phân có giá trị lớn hơn 0o377 (255) tạo ra SyntaxWarning. Trong phiên bản Python tương lai, họ sẽ đưa ra SyntaxError.

2.5.4.4. Ký tự thập lục phân

Chuỗi \xhh biểu thị character với giá trị hex (cơ sở 16) hh:

>>> '\x50'
'P'

Không giống như Tiêu chuẩn C, bắt buộc phải có chính xác hai chữ số thập lục phân.

Theo nghĩa đen, character có nghĩa là byte với giá trị đã cho. Trong một chuỗi ký tự, nó có nghĩa là một ký tự Unicode có giá trị đã cho.

2.5.4.5. Ký tự Unicode được đặt tên

Chuỗi \N{name} biểu thị một ký tự Unicode với name:

>>> '\N{LATIN CAPITAL LETTER P}'
'P'
>>> '\N{SNAKE}'
'🐍'

Trình tự này không thể xuất hiện trong bytes literals.

Thay đổi trong phiên bản 3.3: Hỗ trợ cho name aliases đã được thêm vào.

2.5.4.6. Ký tự Unicode thập lục phân

Các chuỗi \uxxxx\Uxxxxxxxx này biểu thị ký tự Unicode với giá trị hex (cơ sở 16) đã cho. Cần có chính xác bốn chữ số cho \u; chính xác tám chữ số được yêu cầu cho \U. Cái sau có thể mã hóa bất kỳ ký tự Unicode nào.

>>> '\u1234'
'ሴ'
>>> '\U0001f40d'
'🐍'

Những chuỗi này không thể xuất hiện trong bytes literals.

2.5.4.7. Trình tự thoát không được nhận dạng

Không giống như trong Tiêu chuẩn C, tất cả các chuỗi thoát không được nhận dạng đều được giữ nguyên trong chuỗi, nghĩa là the backslash is left in the result:

>>> in('\q')
\q
>>> danh sách('\q')
['\\', 'q']

Lưu ý rằng đối với các ký tự byte, các chuỗi thoát chỉ được nhận dạng ở dạng chuỗi ký tự (\N..., \u..., \U...) thuộc danh mục các ký tự thoát không được nhận dạng.

Thay đổi trong phiên bản 3.6: Các chuỗi thoát không được nhận dạng sẽ tạo ra DeprecationWarning.

Thay đổi trong phiên bản 3.12: Các chuỗi thoát không được nhận dạng sẽ tạo ra SyntaxWarning. Trong phiên bản Python tương lai, họ sẽ đưa ra SyntaxError.

2.5.5. Byte chữ

Bytes literals luôn có tiền tố là 'b' hoặc 'B'; họ tạo ra một phiên bản của loại bytes thay vì loại str. Chúng chỉ có thể chứa các ký tự ASCII; byte có giá trị số từ 128 trở lên phải được biểu thị bằng chuỗi thoát (thường là Ký tự thập lục phân hoặc Ký tự bát phân):

>>> b'\x89PNG\r\n\x1a\n'
b'\x89PNG\r\n\x1a\n'
>>> danh sách(b'\x89PNG\r\n\x1a\n')
[137, 80, 78, 71, 13, 10, 26, 10]

Tương tự, byte 0 phải được biểu thị bằng chuỗi thoát (thường là \0 hoặc \x00).

2.5.6. Chuỗi ký tự thô

Cả chuỗi ký tự và byte đều có thể được bắt đầu bằng một chữ cái 'r' hoặc 'R'; các cấu trúc như vậy được gọi lần lượt là raw string literalsraw bytes literals và coi dấu gạch chéo ngược là ký tự chữ. Kết quả là, trong chuỗi ký tự thô, escape sequences không được xử lý đặc biệt:

>>> r'\d{4}-\d{2}-\d{2}'
'\\d{4}-\\d{2}-\\d{2}'

Ngay cả trong nghĩa đen thô, dấu ngoặc kép có thể được thoát bằng dấu gạch chéo ngược, nhưng dấu gạch chéo ngược vẫn còn trong kết quả; ví dụ: r"\"" là một chuỗi ký tự hợp lệ bao gồm hai ký tự: dấu gạch chéo ngược và dấu ngoặc kép; r"\" không phải là một chuỗi ký tự hợp lệ (ngay cả một chuỗi thô cũng không thể kết thúc bằng số lẻ dấu gạch chéo ngược). Cụ thể là a raw literal cannot end in a single backslash (vì dấu gạch chéo ngược sẽ thoát khỏi ký tự trích dẫn sau). Cũng lưu ý rằng một dấu gạch chéo ngược theo sau là một dòng mới được hiểu là hai ký tự đó như một phần của nghĩa đen, not là phần tiếp theo của dòng.

2.5.7. dây f

Added in version 3.6.

Thay đổi trong phiên bản 3.7: awaitasync for có thể được sử dụng trong các biểu thức trong chuỗi f.

Thay đổi trong phiên bản 3.8: Đã thêm trình xác định gỡ lỗi (=)

Thay đổi trong phiên bản 3.12: Nhiều hạn chế về biểu thức trong chuỗi f đã được loại bỏ. Đáng chú ý, các chuỗi lồng nhau, nhận xét và dấu gạch chéo ngược hiện đã được cho phép.

formatted string literal hoặc f-string là một chuỗi ký tự có tiền tố là 'f' hoặc 'F'. Không giống như các chuỗi ký tự khác, chuỗi f không có giá trị không đổi. Chúng có thể chứa replacement fields được phân cách bằng dấu ngoặc nhọn {}. Các trường thay thế chứa các biểu thức được đánh giá trong thời gian chạy. Ví dụ:

>>> ai = 'không ai cả'
>>> quốc tịch = 'Tây Ban Nha'
>>> f'{who.title()} mong chờ Tòa án dị giáo {quốc tịch}!'
'Không ai mong đợi Tòa án dị giáo Tây Ban Nha!'

Bất kỳ dấu ngoặc nhọn kép nào ({{ hoặc }}) bên ngoài các trường thay thế đều được thay thế bằng dấu ngoặc nhọn đơn tương ứng:

>>> print(f'{{...}}')
{...}

Các ký tự khác bên ngoài các trường thay thế được xử lý giống như các chuỗi ký tự thông thường. Điều này có nghĩa là các chuỗi thoát được giải mã (ngoại trừ khi một chữ cũng được đánh dấu là một chuỗi thô) và có thể có dòng mới trong chuỗi f được trích dẫn ba lần

>>> tên = 'Galahad'
>>> favorite_color = 'xanh'
>>> print(f'{name}:\t{favorite_color}')
Galahad: màu xanh
>>> print(rf"C:\Users\{name}")
C:\Users\Galahad
>>> print(f'''Ba sẽ là số đếm
... và số đếm sẽ là ba.''')
Ba sẽ là số đếm
và số đếm sẽ là ba.

Các biểu thức ở dạng chuỗi ký tự được định dạng được xử lý giống như các biểu thức Python thông thường. Mỗi biểu thức được đánh giá trong ngữ cảnh xuất hiện chuỗi ký tự được định dạng, theo thứ tự từ trái sang phải. Không được phép sử dụng biểu thức trống và cả biểu thức lambda và biểu thức gán := phải được bao quanh bởi dấu ngoặc đơn rõ ràng:

>>> f'{(nửa := 1/2)}, {half * 42}'
'0,5, 21,0'

Được phép sử dụng lại loại trích dẫn chuỗi f bên ngoài bên trong trường thay thế

>>> a = dict(x=2)
>>> f"abc {a["x"]} def"
'abc 2 chắc chắn'

Dấu gạch chéo ngược cũng được phép trong các trường thay thế và được đánh giá theo cách tương tự như trong bất kỳ ngữ cảnh nào khác:

>>> a = ["a", "b", "c"]
>>> print(f"Danh sách a chứa:\n{"\n".join(a)}")
Danh sách a chứa:
một
b
c

Có thể lồng các chuỗi f:

>>> tên = 'thế giới'
>>> f'Lặp lại:{f' xin chào {name}' * 3}'
'Lặp lại: xin chào thế giới xin chào thế giới xin chào thế giới'

Các chương trình Python di động không nên sử dụng nhiều hơn 5 cấp độ lồng nhau.

CPython không giới hạn việc lồng các chuỗi f.

Các biểu thức thay thế có thể chứa các dòng mới trong cả chuỗi f trích dẫn đơn và trích dẫn ba và chúng có thể chứa các nhận xét. Mọi thứ xuất hiện sau # bên trong trường thay thế đều là nhận xét (thậm chí cả dấu ngoặc nhọn và dấu ngoặc kép đóng). Điều này có nghĩa là các trường thay thế bằng nhận xét phải được đóng ở một dòng khác:

>>> a = 2
>>> f"abc{a # This comment }" tiếp tục cho đến hết dòng
... + 3}"
'abc5'

Sau biểu thức, các trường thay thế có thể tùy ý chứa:

  • a debug specifier -- một dấu bằng (=), được bao quanh tùy ý bởi khoảng trắng ở một hoặc cả hai bên;

  • một conversion specifier -- !s, !r hoặc !a; và/hoặc

  • một format specifier có tiền tố là dấu hai chấm (:).

Xem Standard Library section on f-strings để biết chi tiết về cách đánh giá các trường này.

Như phần đó giải thích, format specifiers được chuyển làm đối số thứ hai cho hàm format() để định dạng giá trị trường thay thế. Ví dụ: chúng có thể được sử dụng để chỉ định độ rộng trường và ký tự đệm bằng cách sử dụng Format Specification Mini-Language:

>>> số = 14,3
>>> f'{số:20.7f}'
' 14.3000000'

Công cụ xác định định dạng cấp cao nhất có thể bao gồm các trường thay thế lồng nhau:

>>> kích thước trường_= 20
>>> độ chính xác = 7
>>> f'{number:{field_size}.{precision}f}'
' 14.3000000'

Các trường lồng nhau này có thể bao gồm các trường chuyển đổi của riêng chúng và format specifiers:

>>> số = 3
>>> f'{số:{field_size}}'
' 3'
>>> f'{số:{field_size:05}}'
'000000000000000000003'

Tuy nhiên, các trường lồng nhau này có thể không bao gồm các trường thay thế được lồng sâu hơn.

Không thể sử dụng các chuỗi ký tự được định dạng dưới dạng docstrings, ngay cả khi chúng không bao gồm các biểu thức:

>>> def foo():
... f"Không phải là một chuỗi tài liệu"
...
>>> in(foo.__doc__)
không có

Xem thêm

  • PEP 498 -- Nội suy chuỗi ký tự

  • PEP 701 -- Hình thức hóa cú pháp của chuỗi f

  • str.format(), sử dụng cơ chế chuỗi định dạng liên quan.

2.5.8. dây chữ T

Added in version 3.14.

template string literal hoặc t-string là một chuỗi ký tự có tiền tố là 't' hoặc 'T'. Các chuỗi này tuân theo các quy tắc cú pháp giống như formatted string literals. Để biết sự khác biệt trong quy tắc đánh giá, hãy xem Standard Library section on t-strings

2.5.9. Ngữ pháp chính thức cho chuỗi f

Chuỗi F được xử lý một phần bởi lexical analyzer, tạo ra các mã thông báo FSTRING_START, FSTRING_MIDDLEFSTRING_END, và một phần bởi trình phân tích cú pháp, xử lý các biểu thức trong trường thay thế. Cách phân chia công việc chính xác là chi tiết triển khai CPython.

Tương ứng, ngữ pháp chuỗi f là sự kết hợp của lexical and syntactic definitions.

Khoảng trắng có ý nghĩa quan trọng trong những tình huống sau:

  • Có thể không có khoảng trắng trong FSTRING_START (giữa tiền tố và trích dẫn).

  • Khoảng trắng trong FSTRING_MIDDLE là một phần của nội dung chuỗi ký tự.

  • Trong fstring_replacement_field, nếu có f_debug_specifier, tất cả khoảng trắng sau dấu ngoặc mở cho đến f_debug_specifier, cũng như khoảng trắng ngay sau f_debug_specifier, đều được giữ lại như một phần của biểu thức.

    Biểu thức không được xử lý trong giai đoạn mã thông báo; nó được truy xuất từ mã nguồn bằng cách sử dụng vị trí của mã thông báo { và mã thông báo sau =.

Định nghĩa FSTRING_MIDDLE sử dụng negative lookaheads (!) để biểu thị các ký tự đặc biệt (dấu gạch chéo ngược, dòng mới, {, }) và chuỗi (f_quote).

fstring:    FSTRING_START fstring_middle* FSTRING_END

FSTRING_START:      fstringprefix ("'" | '"' | "'''" | '"""')
FSTRING_END:        f_quote
fstringprefix:      <("f" | "fr" | "rf"), case-insensitive>
f_debug_specifier:  '='
f_quote:            <the quote character(s) used in FSTRING_START>

fstring_middle:
   | fstring_replacement_field
   | FSTRING_MIDDLE
FSTRING_MIDDLE:
   | (!"\" !newline !'{' !'}' !f_quote) source_character
   | stringescapeseq
   | "{{"
   | "}}"
   | <newline, in triple-quoted f-strings only>
fstring_replacement_field:
   | '{' f_expression [f_debug_specifier] [fstring_conversion]
         [fstring_full_format_spec] '}'
fstring_conversion:
   | "!" ("s" | "r" | "a")
fstring_full_format_spec:
   | ':' fstring_format_spec*
fstring_format_spec:
   | FSTRING_MIDDLE
   | fstring_replacement_field
f_expression:
   | ','.(conditional_expression | "*" or_expr)+ [","]
   | yield_expression

Ghi chú

Trong đoạn mã ngữ pháp ở trên, các quy tắc f_quoteFSTRING_MIDDLE tùy theo ngữ cảnh -- chúng phụ thuộc vào nội dung của FSTRING_START của fstring bao quanh gần nhất.

Việc xây dựng một ngữ pháp trang trọng mang tính truyền thống hơn từ mẫu này được xem như một bài tập dành cho người đọc.

Ngữ pháp cho chuỗi t giống hệt với ngữ pháp cho chuỗi f, với t thay vì f ở đầu quy tắc và tên mã thông báo cũng như trong tiền tố.

tstring:    TSTRING_START tstring_middle* TSTRING_END

<rest of the t-string grammar is omitted; see above>

2.6. Chữ số

Mã thông báo NUMBER đại diện cho các chữ số, trong đó có ba loại: số nguyên, số dấu phẩy động và số ảo.

NUMBER: integer | floatnumber | imagnumber

Giá trị số của một chữ số giống như khi nó được truyền dưới dạng một chuỗi tới hàm tạo của lớp int, float hoặc complex tương ứng. Lưu ý rằng không phải tất cả các đầu vào hợp lệ cho các hàm tạo đó đều là các giá trị bằng chữ hợp lệ.

Chữ số không bao gồm dấu; một cụm từ như -1 thực ra là một biểu thức bao gồm toán tử một ngôi '-' và 1 theo nghĩa đen.

2.6.1. Chữ số nguyên

Chữ nguyên biểu thị số nguyên. Ví dụ:

7
3
2147483647

Không có giới hạn về độ dài của các chữ nguyên ngoài những gì có thể được lưu trữ trong bộ nhớ khả dụng

7922816251426433759354395033679228162514264337593543950336

Dấu gạch dưới có thể được sử dụng để nhóm các chữ số nhằm nâng cao khả năng đọc và được bỏ qua khi xác định giá trị số của chữ. Ví dụ: các chữ sau đây là tương đương:

100_000_000_000
100000000000
1_00_00_00_00_000

Dấu gạch dưới chỉ có thể xảy ra giữa các chữ số. Ví dụ: _123, 321_123__321 là các chữ hợp lệ not.

Các số nguyên có thể được chỉ định ở dạng nhị phân (cơ sở 2), bát phân (cơ sở 8) hoặc thập lục phân (cơ sở 16) bằng cách sử dụng các tiền tố 0b, 0o0x tương ứng. Các chữ số thập lục phân từ 10 đến 15 được biểu thị bằng các chữ cái A-F, không phân biệt chữ hoa chữ thường. Ví dụ:

0b100110111
0b_1110_0101
0o177
0o377
0xdeadbeef
0xDead_Thịt 

Dấu gạch dưới có thể theo sau mã xác định cơ sở. Ví dụ: 0x_1f là một chữ hợp lệ, nhưng 0_x1f0x__1f thì không.

Không được phép sử dụng số 0 đứng đầu trong số thập phân khác 0. Ví dụ: 0123 không phải là một chữ hợp lệ. Điều này nhằm mục đích phân biệt với các chữ bát phân kiểu C mà Python đã sử dụng trước phiên bản 3.0.

Về mặt hình thức, các số nguyên được mô tả bằng các định nghĩa từ vựng sau:

integer:      decinteger | bininteger | octinteger | hexinteger | zerointeger
decinteger:   nonzerodigit (["_"] digit)*
bininteger:   "0" ("b" | "B") (["_"] bindigit)+
octinteger:   "0" ("o" | "O") (["_"] octdigit)+
hexinteger:   "0" ("x" | "X") (["_"] hexdigit)+
zerointeger:  "0"+ (["_"] "0")*
nonzerodigit: "1"..."9"
digit:        "0"..."9"
bindigit:     "0" | "1"
octdigit:     "0"..."7"
hexdigit:     digit | "a"..."f" | "A"..."F"

Thay đổi trong phiên bản 3.6: Dấu gạch dưới hiện được phép cho mục đích nhóm theo nghĩa đen.

2.6.2. Chữ dấu phẩy động

Các chữ có dấu phẩy động (float), chẳng hạn như 3.14 hoặc 1.5, biểu thị approximations of real numbers.

Chúng bao gồm các phần integerfraction, mỗi phần bao gồm các chữ số thập phân. Các phần được phân tách bằng dấu thập phân, .:

2.71828
4.0

Không giống như các chữ số nguyên, các số 0 đứng đầu được cho phép. Ví dụ: 077.010 là hợp pháp và biểu thị cùng số với 77.01.

Giống như trong các số nguyên, dấu gạch dưới đơn có thể xuất hiện giữa các chữ số để giúp dễ đọc:

96_485.332_123
3.14_15_93

Một trong hai phần này, nhưng không được cả hai, có thể trống. Ví dụ:

10. # (tương đương 10.0)
0,001 # (tương đương 0,001)

Theo tùy chọn, số nguyên và phân số có thể được theo sau bởi exponent: chữ cái e hoặc E, theo sau là một dấu hiệu tùy chọn, + hoặc - và một số có cùng định dạng với phần nguyên và phần phân số. e hoặc E đại diện cho "lần mười được nâng lên lũy thừa của":

1.0e3 # (đại diện cho 1.0×10³ hoặc 1000.0)
1.166e-5 # (đại diện cho 1.166×10⁻⁵ hoặc 0,00001166)
6.02214076e+23 # (đại diện cho 6.02214076×10²³ hoặc 602214076000000000000000.)

Trong các số float chỉ có phần số nguyên và số mũ, dấu thập phân có thể bị bỏ qua:

1e3 # (tương đương 1.e3 và 1.0e3)
0e0 # (tương đương với 0.)

Về mặt hình thức, các chữ có dấu phẩy động được mô tả bằng các định nghĩa từ vựng sau:

floatnumber:
   | digitpart "." [digitpart] [exponent]
   | "." digitpart [exponent]
   | digitpart exponent
digitpart: digit (["_"] digit)*
exponent:  ("e" | "E") ["+" | "-"] digitpart

Thay đổi trong phiên bản 3.6: Dấu gạch dưới hiện được phép cho mục đích nhóm theo nghĩa đen.

2.6.3. Chữ tưởng tượng

Python có các đối tượng complex number nhưng không có chữ phức tạp. Thay vào đó, imaginary literals biểu thị số phức có phần thực bằng 0.

Ví dụ, trong toán học, số phức 3+4.2i được viết dưới dạng số thực 3 cộng với số ảo 4.2i. Python sử dụng cú pháp tương tự, ngoại trừ đơn vị ảo được viết là j chứ không phải i:

3+4.2j

Đây là biểu thức bao gồm integer literal 3, operator '+' và imaginary literal 4.2j. Vì đây là ba mã thông báo riêng biệt nên khoảng trắng được cho phép giữa chúng:

3 + 4.2j

Không cho phép khoảng trắng within mỗi mã thông báo. Đặc biệt, hậu tố j không được tách khỏi số đứng trước nó.

Số trước j có cú pháp giống như chữ số dấu phẩy động. Vì vậy, sau đây là những chữ tưởng tượng hợp lệ:

4.2j
3,14j
10.j
.001j
1e100j
3,14e-10j
3.14_15_93j

Không giống như dấu phẩy động, dấu thập phân có thể được bỏ qua nếu số ảo chỉ có phần nguyên. Số vẫn được đánh giá là số dấu phẩy động, không phải số nguyên:

10j
0j
1000000000000000000000000j # equivalent đến 1e+24j

Hậu tố j không phân biệt chữ hoa chữ thường. Điều đó có nghĩa là bạn có thể sử dụng J thay thế

3,14J # equivalent đến 3,14j

Về mặt hình thức, các nghĩa đen tưởng tượng được mô tả theo định nghĩa từ vựng sau:

imagnumber: (floatnumber | digitpart) ("j" | "J")

2.7. Toán tử và dấu phân cách

Ngữ pháp sau đây xác định mã thông báo operatordelimiter, nghĩa là loại mã thông báo OP chung. list of these tokens and their names cũng có sẵn trong tài liệu mô-đun token.

OP:
   | assignment_operator
   | bitwise_operator
   | comparison_operator
   | enclosing_delimiter
   | other_delimiter
   | arithmetic_operator
   | "..."
   | other_op

assignment_operator:   "+=" | "-=" | "*=" | "**=" | "/="  | "//=" | "%=" |
                       "&=" | "|=" | "^=" | "<<=" | ">>=" | "@="  | ":="
bitwise_operator:      "&"  | "|"  | "^"  | "~"   | "<<"  | ">>"
comparison_operator:   "<=" | ">=" | "<"  | ">"   | "=="  | "!="
enclosing_delimiter:   "("  | ")"  | "["  | "]"   | "{"   | "}"
other_delimiter:       ","  | ":"  | "!"  | ";"   | "="   | "->"
arithmetic_operator:   "+"  | "-"  | "**" | "*"   | "//"  | "/"   | "%"
other_op:              "."  | "@"

Ghi chú

Nói chung, operators được sử dụng để kết hợp expressions, trong khi delimiters phục vụ các mục đích khác. Tuy nhiên, không có sự phân biệt rõ ràng và chính thức giữa hai loại này.

Một số mã thông báo có thể đóng vai trò là toán tử hoặc dấu phân cách, tùy thuộc vào cách sử dụng. Ví dụ: * vừa là toán tử nhân vừa là dấu phân cách được sử dụng để giải nén chuỗi và @ vừa là phép nhân ma trận vừa là dấu phân cách giới thiệu các ký tự trang trí.

Đối với một số token, sự khác biệt là không rõ ràng. Ví dụ: một số người coi ., () là các dấu phân cách, trong khi những người khác coi toán tử getattr() và (các) toán tử gọi hàm.

Một số toán tử của Python, như and, ornot in, sử dụng mã thông báo keyword thay vì "ký hiệu" (mã thông báo toán tử).

Một chuỗi gồm ba dấu chấm liên tiếp (...) có một ý nghĩa đặc biệt như một chữ Ellipsis.