Hướng dẫn syntax error print python - lỗi cú pháp print python

Python nổi tiếng vì cú pháp đơn giản của nó. Tuy nhiên, khi bạn đang học Python lần đầu tiên hoặc khi bạn đến với Python với một nền tảng vững chắc ở ngôn ngữ lập trình khác, bạn có thể tìm hiểu những thứ mà Python không cho phép. Nếu bạn nhận được lỗi

>>> len('hello') == 5
True
1 khi chạy code của bạn thì bài viết này sẽ giúp đỡ bạn giải quyết vấn đề này. Xuyên suốt tutorial, bạn sẽ thấy các ví dụ điển hình về lỗi cú pháp trong Python hà học cách giải quyết chúng.

Đến cuối tutorial này, bạn có thể:

  • Xác định cú pháp không hợp lệ trong Python
  • Hiểu được traceback của
    >>> len('hello') == 5
    True
    
    1
  • Sửa và phòng tránh lỗi cú pháp

Invalid Syntax in Python

Khi bạn chạy code, đầu tiên trình biên dịch sẽ phân tích (parse) để convert nó thành Python byte code - đoạn code sau đó được chạy. Trình biên dịch sẽ tìm các lỗi về cú pháp trong bước đầu tiên trong quá trình xử lý chương trình, hay còn gọi là bước phân tích (parsing stage). Nếu trình biên dịch không thể parse đoạn code thành công thì có nghĩa là bạn đã sử dụng sai cú pháp ở đâu đó trong code của bạn. Trình biên dịch sẽ cố gắng chỉ cho bạn thấy chỗ mà lỗi đó xảy ra.

Khi bạn tiếp Python lần đầu tiên, bạn có thể bị nản khi bạn lỗi

>>> len('hello') == 5
True
1. Python sẽ giúp bạn xác định chỗ mà bạn sử dụng sai cú pháp nhưng traceback nó đưa ra có thể khó hiểu một chút. Thi thoảng, code nó trỏ tới hoàn toàn hợp lý.

Note: Nếu code đúng cú pháp, bạn có thể nhận được các exception khác được raise lên mà không phải là

>>> len('hello') == 5
True
1. Để tìm hiểu thêm về các exception khác và cách xử lý chúng, xem ở đây: Nếu code đúng cú pháp, bạn có thể nhận được các exception khác được raise lên mà không phải là
>>> len('hello') == 5
True
1. Để tìm hiểu thêm về các exception khác và cách xử lý chúng, xem ở đây

Bạn không thể xử lý lỗi cú pháp như các exception khác. Thậm chí, nếu bạn cố gắng đưa đoạn code sai cú pháp vào trong một khối

>>> len('hello') == 5
True
5, bạn vẫn sẽ trình biên dịch raise lên lỗi
>>> len('hello') == 5
True
1.

SyntaxError Exception and Traceback

Khi trình biên dịch gặp phải lỗi cú pháp, Python sẽ raise lên exception

>>> len('hello') == 5
True
7 và cung cấp trace back với một số thông tin hữu ích để giúp bạn debug. Đây là đoạn code chứa lỗi cú pháp:

ages = {

    'pam': 24,

    'jim': 24

    'michael': 43

}

print(f'Michael is {ages["michael"]} years old.')

Bạn có thể thấy cú pháp không hợp lệ ở trong dict dòng 4. Mục thứ hai,

>>> len('hello') == 5
True
8, thiếu dấu phẩy. Nếu bạn chạy đoạn code, bạn sẽ thu được traceback sau:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax

Chú ý rằng traceback sẽ chỉ ra lỗi ở dòng 5, chứ không phải 4. Trình biên dịch Python đã cố chỉ ra vị trí lỗi. Tuy nhiên, nó chỉ có thể trỏ tới nơi nó bắt được lỗi đầu tiên. Khi nhận được traceback và traceback trông có ý nghĩa, bạn cần nhìn loại đoạn code để xác định chỗ sai.

Trong ví dụ bên trên, không có với đề với việc thiếu dấu phẩy mà phụ thuộc vào việc cái gì theo sau nó. Ví dụ, việc không có dấu phẩy sau

>>> len('hello') == 5
True
9 ở dòng 5 chẳng ảnh hưởng gì. Nhưng một khi trình biên dịch bắt gặp điều gì đó bất ổn, nó chỉ có thể trỏ ngay tới dòng code đầu tiên mà nó không hiểu.

Note: Tutorial này giả định rằng bạn đã có kiến thức cơ bản về traceback trong Python. Để tìm hiểu thêm về traceback và cách đọc hiểu chúng, đọc bài viết này. Tutorial này giả định rằng bạn đã có kiến thức cơ bản về traceback trong Python. Để tìm hiểu thêm về traceback và cách đọc hiểu chúng, đọc bài viết này.

Có một vài thành phần của

>>> len('hello') == 5
True
1 có thể giúp bạn xác định vị trí lỗi:

  • File name - file mà lỗi cú pháp được tìm thấy - file mà lỗi cú pháp được tìm thấy
  • Line number - nội dung dòng lỗi - nội dung dòng lỗi
  • Caret - vị trí chính xác mà lỗi được bắt gặp - vị trí chính xác mà lỗi được bắt gặp
  • Error message - xuất hiện ngay sau kiểu lỗi
    >>> len('hello') == 5
    True
    
    1, nội dung lỗi giúp bạn xác định vấn đề
    - xuất hiện ngay sau kiểu lỗi
    >>> len('hello') == 5
    True
    
    1, nội dung lỗi giúp bạn xác định vấn đề

Trong ví dụ trên, file name là

>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
2, line number là
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
3 và caret trỏ vào dấu nháy đơn của key
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
4. Traceback
>>> len('hello') == 5
True
1 có thể không chỉ ra vấn đề thực sự nhưng nó sẽ chỉ tới vị trí đầu tiên mà trình biên dịch không hiểu.

Có hai exception khác bạn có thể sẽ thấy Python raise lên. Nó tương tự như

>>> len('hello') == 5
True
1 nhưng dưới những cái tên khác:

  1. >>> fro i in range(10):
      File "", line 1
        fro i in range(10):
            ^
    SyntaxError: invalid syntax
    
    7
  2. >>> fro i in range(10):
      File "", line 1
        fro i in range(10):
            ^
    SyntaxError: invalid syntax
    
    8

Những exception này đều kế thừa từ

>>> len('hello') == 5
True
1 nhưng chúng là những trường hợp đặc biệt liên quan đến indentation (thụt đầu dòng).
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
7 được raise lên khi các mức indent không khớp nhau. Còn
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
8 xuất hiện khi code của bạn sử dụng cả tab và space trong cùng một file. Chúng ta sẽ xét kỹ hơn đến những exception này trong phần sau.

Common Syntax Problems

Khi chúng ta bắt gặp

>>> len('hello') == 5
True
1 lần đầu tiên, việc biết lý do lỗi xảy ra và cách fix nó thực sự hữu ích. Trong các phần tiếp theo, chúng ta sẽ thấy một số lý do phổ biến mà
>>> len('hello') == 5
True
1 có thể được raise lên và cách bạn có thể fix chúng.

Misusing the Assignment Operator (=)

Có vài trường hợp trong Python mà bạn không để gán các object ví dụ như với chuỗi và lời gọi hàm:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal

Ví dụ đầu tiên cố gắng gán giá trị

>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
3 cho lời gọi
>>> for i range(10):
  File "", line 1
    for i range(10):
              ^
SyntaxError: invalid syntax
5. Message
>>> len('hello') == 5
True
1 rất hữu ích trong trường hợp này. Nó nói rằng là bạn không thể gán một giá trị cho một lời gọi hàm.

Ví dụ thứ hai và thứ ba cố gắng gái một string với một số nguyên cho các chuỗi. Quy tắc tương tự đúng với các giá trị chuỗi khác. Một lần nữa, traceback chỉ ra vấn đề xảy ra khi bạn cố gắng gán một giá trị cho một chuỗi.

Note: Các ví dụ bên trên thiếu dòng code được lặp lại và dấu mũ (^) chỉ ra vấn đề trong traceback. Exception và traceback mà bạn nhìn thấy sẽ khác khi bạn đang ở trong một phiên REPL so với việc bạn chạy code từ một file. Nếu code này nằm ở trong file, bạn sẽ nhận được dòng code lặp và dấu mũ. Các ví dụ bên trên thiếu dòng code được lặp lại và dấu mũ (^) chỉ ra vấn đề trong traceback. Exception và traceback mà bạn nhìn thấy sẽ khác khi bạn đang ở trong một phiên REPL so với việc bạn chạy code từ một file. Nếu code này nằm ở trong file, bạn sẽ nhận được dòng code lặp và dấu mũ.

Có lẽ là bạn sẽ chẳng bao giờ có ý định gán một giá trị cho một chuỗi hoặc lời gọi hàm. Các lỗi trên xảy ra chỉ khi bạn vô tình quên mất một dấu "=" khi bạn muốn thực hiện phép so sánh:

>>> len('hello') == 5
True

Đa số các trường hợp, khi Python nói rằng bạn đang thực hiện phép gán với một object mà không thể được gán, đầu tiên bạn nên kiểm tra chắc chắn rằng xem câu lệnh là một lệnh gán hay là một biểu thức Boolean. Bạn cũng có thể gặp vấn đề này khi bạn đang cố gắng gán một giá trị với các keyword. Chúng ta sẽ đề cập đến trường hợp này trong mục sau.

Misspelling, Missing, or Misusing Python Keywords

Các keyword trong Python là một tập các protected word có ý nghĩa đặc biệt trong Python. Đây là những từ khóa bạn không thể sử dụng như là các định danh, biến hoặc tên hàm. Chúng là một phần của ngôn ngữ và chỉ có thể sử dụng trong ngữ cảnh mà Python cho phép.protected word có ý nghĩa đặc biệt trong Python. Đây là những từ khóa bạn không thể sử dụng như là các định danh, biến hoặc tên hàm. Chúng là một phần của ngôn ngữ và chỉ có thể sử dụng trong ngữ cảnh mà Python cho phép.

Những trường hợp mà bạn có thể nhầm lẫn sử dụng các keyword:

  1. Sai chính tả
  2. Thiếu keyword
  3. Sử dụng sai keyword

Nếu bạn viết sai chính tả, bạn sẽ thấy lỗi

>>> len('hello') == 5
True
1. Ví dụ đầy là điều xảy ra khi bạn viết sai keyword
>>> for i range(10):
  File "", line 1
    for i range(10):
              ^
SyntaxError: invalid syntax
8:

>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax

Message là

>>> for i range(10):
  File "", line 1
    for i range(10):
              ^
SyntaxError: invalid syntax
9 - không quá hữu ích. Traceback trỏ tới vị trí đầu tiên mà Python phát hiện có cái gì đó sai. Để fix các lỗi kiểu như này, hãy chắc chắn rằng một keyword đều đúng.

Một vấn đề phổ biến khác chính là việc bạn quên keyword:

>>> for i range(10):
  File "", line 1
    for i range(10):
              ^
SyntaxError: invalid syntax

Một lần nữa, message lại không hữu ích nhưng traceback lại trỏ tới đúng vị trí. Nếu bạn di chuyển dấu mũ ngược lại bạn sẽ đấy keyword

>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
0 bị thiếu trong cú pháp của vòng lặp
>>> for i range(10):
  File "", line 1
    for i range(10):
              ^
SyntaxError: invalid syntax
8.

Bạn cũng có thể sử dụng sai protected keyword. Hãy nhớ rằng, các keyword chỉ được sử dụng trong một số trường hợp nhất định. Nếu bạn sử dụng sai chúng bạn cũng sẽ nhận được lỗi sai cú pháp. Một ví dụ điển hình là việc sử dụng

>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
2 hoặc
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
3 ngoài vòng lặp. Điều này có thể dễ dàng xảy ra khi bạn di chuyển một đoạn code ra khỏi một vòng lặp:

>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop

Ở đây, Python đã làm tốt việc thông báo chính xác lỗi cho bạn biết. Message "

>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
4" và "
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
5" giúp bạn biết việc mình cần làm.

Một ví dụ khác là nếu bạn cố gắng gán một keyword cho một biến hoặc sử dụng keyword để khai báo hàm:

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax

Nếu bạn thử gắn một giá trị cho

>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
6 hoặc khi bạn định nghĩa một hàm với tên
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
6, bạn sẽ gặp lỗi
>>> len('hello') == 5
True
1 và thấy message
>>> names = ['pam', 'jim', 'michael']
>>> if 'jim' in names:
...     print('jim found')
...     break
...
  File "", line 3
SyntaxError: 'break' outside loop

>>> if 'jim' in names:
...     print('jim found')
...     continue
...
  File "", line 3
SyntaxError: 'continue' not properly in loop
9 một lần nữa.

Giải quyết lỗi cú pháp này có thể khó hơn một chút bởi đoạn code nhìn bên ngoài trông thì khá ổn. Nếu code trông ổn mà bạn vẫn gặp lỗi

>>> len('hello') == 5
True
1 thì bạn nên cân nhắc kiểm tra tên biến và hàm mà bạn muốn sử dụng.

Danh sách các protected keyword sẽ thay đổi theo phiên bản của Python. Ví dụ trong Python 3.6 bạn có thể sử dụng

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
1 làm tên biến hoặc tên hàm nhưng trong Python 3.7 thì nó lại nằm trong danh sách keyword. Bây giờ, nếu bạn thử sử dụng
>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
1 làm tên biến hoặc tên hàm, lỗi
>>> len('hello') == 5
True
1 sẽ bị raise lên nếu bạn sử dụng Python 3.7 hoặc cao hơn.

Một ví dụ khác của vấn đề này chính là

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
4 - có sự khác nhau giữa Python 2 và 3:

Phiên bảnKiểu của
>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
4
Nhận giá trị
Python 2 keyword không
Python 3 built-in function

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
4 là một keyword trong Python 2 nên bạn không thể gán giá trị cho nó. Tuy nhiên trong Python 3, nó là một hàm có sẵn có thể được gán các giá trị.

Bạn có thể chạy code sau để thấy một danh sách keyword trong phiên bản Python mà bạn sử dụng:

import keyword
print(keyword.kwlist)

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
7 là một hàm hữu ích dùng để kiểm tra xem một từ có là keyword hay không:

>>> import keyword; keyword.iskeyword('pass')
True

Missing Parentheses, Brackets, and Quotes

Thông thường, nguyên nhân gây ra lỗi cú pháp trong Python là do thiếu dấu đơn, ngoặc vuông hoặc dấu nháy đơn/kép đóng. Những thiếu xót này khó phát hiện ra ở những dòng dài mà có nhiều dấu ngoặc đơn lồng nhau hoặc ở những khối code nhiều dòng. Bạn có thể phát hiện ra điều này nhờ sự giúp đỡ của traceback:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
0

Ở đây, traceback chỉ ra chỗ code không hợp lệ là ở vị trí

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
8. Để fix lỗi này, bạn có thể sử dụng hai cách:

  1. Thêm ký tự thoát
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    9 trước dấu nháy đơn thứ hai (
    import keyword
    print(keyword.kwlist)
    
    0)
  2. Bao quanh string với cặp dấu nháy kép (
    import keyword
    print(keyword.kwlist)
    
    1)

Một sai lầm thường gặp khác là quên đóng string:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
1

Lần này, dầu mũ trong traceback trỏ chính xác tới vị trí code có vấn đề. Thông báo

>>> len('hello') == 5
True
1, "
import keyword
print(keyword.kwlist)
3", đã cụ thể và hữu ích hơn một chút trong việc xác định vấn đề. Điều này cũng có nghĩa là trình biên dịch Python đã đi tới tận cùng của dòng code đó. Để fix lỗi này, hãy đóng string với dấu nháy mà bạn đã sử dụng để mở string. Trong trường hợp này là dấu nháy kép
import keyword
print(keyword.kwlist)
4.

Việc thiếu dấu nháy trong các statement thuộc một f-string có thể dẫn tới lỗi cú pháp:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
2

Ở đây, việc tham chiếu tới dict

import keyword
print(keyword.kwlist)
5 bên trong f-string bị thiếu dấu nháy kép đóng ở tham chiếu key. Traceback nhận được là:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
3

Python xác định vấn đề và cho bạn biết vấn đề nằm ở trong f-string. Message "unterminated string" cũng chỉ ra vấn đề là gì. Dấu mũ trong trường hợp này chỉ trỏ tới vị trí bắt đầu của f-string.

Việc này có thể không có ý nghĩa khi mà dấu mũ trỏ tới khu vực của f-string nhưng nó lại không thu hẹp vị trí mà chúng ta cần quan tâm. Có một string chưa kết thúc bên trong f-string. Bạn chỉ việc tìm ra nó. Để fix lỗi này, hãy đảm bảo rằng tất cả các dấu nháy trong f-string và ngoặc nhọn phải đầy đủ.

Lỗi tương tự xảy ra khi thiếu ngoặc đơn và ngoặc vuông. Ví dụ, nếu bạn quên dấu ngoặc vuông dùng để đóng một list, Python sẽ phát hiện và trỏ tới đó. Tuy nhiên, không có nhiều sự khác biệt trong những trường hợp này. Trong ví dụ đầu tiên, chúng ta quên dấu ngoặc vuông đóng:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
4

Khi chạy đoạn code này, bạn sẽ được nhắc nhở rằng có lỗi khi gọi

import keyword
print(keyword.kwlist)
6:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
5

Điều xảy ra ở đây chính là việc Python nghĩ là list gồm ba phần tử:

import keyword
print(keyword.kwlist)
7,
import keyword
print(keyword.kwlist)
8 và
import keyword
print(keyword.kwlist)
9. Python sử dụng khoảng trắng (whitespace) để nhóm các thứ lại với nhau và bởi vì không có dấu phẩy và ngoặc vuông ngăn
>>> import keyword; keyword.iskeyword('pass')
True
0 với
>>> import keyword; keyword.iskeyword('pass')
True
1, Python gộp chúng lại thành phần tử thứ ba của list.

Một biến thể nữa là thêm một dấu phẩy sau phần tử cuối cùng của list trong khi vẫn quên dấu ngoặc vuông đóng:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
6

Bây giờ bạn nhận được một traceback khác:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
7

Trong ví dụ trước đó,

>>> import keyword; keyword.iskeyword('pass')
True
0 và
>>> import keyword; keyword.iskeyword('pass')
True
1 được nhóm lại thành một phần tử nhưng ở đây bạn thấy dấu phẩy sẽ ngăn cách chúng. Bây giờ việc gọi
>>> import keyword; keyword.iskeyword('pass')
True
1 được thêm vào như là phần tử thứ tư của list và Python chạy tới cuối file mà không có dấu ngoặc vuông đóng. Traceback nói cho bạn biết rằng Python đã đọc hết file (EOF) nhưng nó vẫn mong chờ một cái gì đó khác.

Trong ví dụ này, Python mong chờ một dấu ngoặc vuông đóng

>>> import keyword; keyword.iskeyword('pass')
True
5 nhưng dòng được nhắc và dấu mũ không thực sự hữu ích. Việc thiếu dấu ngoặc đơn hoặc dấu ngoặc đơn khiến Python rất khó để nhận ra. Đôi khi điều duy nhất bạn có thể làm là bắt đầu từ dấu mũ và quay ngược lại cho đến khi bạn phát hiện ra những thiếu sót.

Mistaking Dictionary Syntax

Trước đó bạn đã thấy rằng bạn có thể gặp lỗi

>>> len('hello') == 5
True
1 nếu bạn quên dấu phẩy ở một phần tử dict. Một dạng khác của lỗi cú pháp với dict là việc sử dụng dấu "=" để ngăn cách các key và value thay vì ":":

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
8

Một lần nữa thông báo lỗi lại không hữu ích. Tuy nhiên, dòng nhắc lại và dấu mũ lại rất hữu ích! Chúng trỏ tới đúng ký tự có vấn đề.

Để fix lỗi này, bạn có thể thay thế các dấu "=" với dấu ":". Bạn cũng có thể chuyển sang dùng

>>> import keyword; keyword.iskeyword('pass')
True
7:

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
9

Bạn có thể sử dụng

>>> import keyword; keyword.iskeyword('pass')
True
7 để khai báo dict nếu cú pháp này hữu ích hơn.

Using the Wrong Indentation

Có hai class con của

>>> len('hello') == 5
True
1 dành riêng cho các vấn đề về indentation:

  1. IndentationError
  2. TabError

Trong khi các ngôn ngữ lập trình khác sử ngoặc nhọn để khai báo một khối code, Python lại sử dụng

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
00 (khoảng trắng). Python sẽ raise lên lỗi
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
7 nếu có một dòng code trong khối có số khoảng trắng không đúng:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
0

Điều này có thể khá khó để phát hiện nhưng dòng thứ 5 chỉ bị thụt có hai khoảng trắng. May thay Python lại dễ dàng phát hiện và nói cho bạn biết vấn đề là gì:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
1

Mặc dù traceback trông khá giống traceback của

>>> len('hello') == 5
True
1, nó thực tế lại là một
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
7. Thông báo lỗi rất hữu ích. Nó nói cho bạn biết mức indentation của dòng code không khớp các mức indentation khác. Bạn có thể sửa lỗi này một cách nhanh chóng bằng cách đảm bảo rằng đoạn code được thụt lùi sao cho đúng mức indentation mong muốn.

Một loại

>>> len('hello') == 5
True
1 khác là
>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
8 - error nói cho bạn biết rằng có một dòng có sử dụng tab hoặc space cho mục đích indentation trong khi cái còn lại được dùng ở một nơi khác trong file. Điều này có thể bị bỏ qua cho đến khi Python chỉ ra lỗi đó cho bạn biết!

Nếu tab size trùng với số khoảng trắng trong mỗi mực indentation thì mọi thứ chẳng có vẻ gì lạ. Tuy nhiên, nếu một dòng được indent bằng space và một dòng khác lại được indent với tab thì Python sẽ chỉ cho bạn thấy vấn đề:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
2

Ở đây, dòng 5 được indent với một ký tự tab gồm 4 space. Khối code này có thể nhìn có vẻ hoàn hảo hoặc hoàn toàn sai, tùy vào setting hệ thống của bạn.

Tuy nhiên, Python sẽ để ý vấn đề này ngay lập tức. Nhưng trước khi bạn chạy đoạn code để xem Python sẽ nói cho bạn biết cái gì sai, hãy xem ví dụ sau:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
3

Chú ý là sự khác biệt trong hiển thị giữa ba ví dụ trên. Trừ dòng 5 sử dụng single tab thì các dòng code khác sử dụng 4 space cho một mức indentation. Độ rộng của tab thay đổi dựa vào tab width setting:tab width setting:

  • Nếu tab width là 4 thì lệnh
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    4 nhìn có vẻ nằm ngoài vòng lặp
    >>> for i range(10):
      File "", line 1
        for i range(10):
                  ^
    SyntaxError: invalid syntax
    
    8. Console sẽ in "done" ở cuối vòng lặp.
    thì lệnh
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    4 nhìn có vẻ nằm ngoài vòng lặp
    >>> for i range(10):
      File "", line 1
        for i range(10):
                  ^
    SyntaxError: invalid syntax
    
    8. Console sẽ in "done" ở cuối vòng lặp.
  • Nếu tab width là 8, chuẩn của rất nhiều hệ thống, thì lệnh
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    4 trông có vẻ nằm trong vòng lặp
    >>> for i range(10):
      File "", line 1
        for i range(10):
                  ^
    SyntaxError: invalid syntax
    
    8. Console sẽ in "done" sau mỗi số.
    , chuẩn của rất nhiều hệ thống, thì lệnh
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    4 trông có vẻ nằm trong vòng lặp
    >>> for i range(10):
      File "", line 1
        for i range(10):
                  ^
    SyntaxError: invalid syntax
    
    8. Console sẽ in "done" sau mỗi số.
  • Nếu tab width là 3 thì lệnh
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    4 nhìn có vẻ chẳng thuộc về đâu. Trong trường hợp này, dòng 5 không khớp với một mức indentation nào cả.
    thì lệnh
    >>> pass = True
      File "", line 1
        pass = True
             ^
    SyntaxError: invalid syntax
    
    >>> def pass():
      File "", line 1
        def pass():
               ^
    SyntaxError: invalid syntax
    
    4 nhìn có vẻ chẳng thuộc về đâu. Trong trường hợp này, dòng 5 không khớp với một mức indentation nào cả.

Khi bạn chạy đoạn code, bạn sẽ nhận được lỗi và traceback sau:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
4

Chú ý rằng ở đây ta nhận được

>>> fro i in range(10):
  File "", line 1
    fro i in range(10):
        ^
SyntaxError: invalid syntax
8 thay vì
>>> len('hello') == 5
True
1. Python chỉ ra dòng có vấn đề và cung cấp cho bạn một thông báo hữu ích. Nó nói cho bạn rằng tab và space bị sử dụng lẫn lộn cho indentation trong cùng một file.

Giải pháp cho vấn đề này là sử dụng hoặc là tab hoặc là space cho indentation, chứ không phải là cả hai.

Defining and Calling Functions

Bạn có thể gặp lỗi cú pháp khi bạn định nghĩa hoặc gọi hàm. Ví dụ, bạn sẽ thấy SyntaxError nếu bạn sử dụng ";" thay vì ":" ở cuối cuối nghĩa hàm:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
5

Traceback ở đây rất hữu ích với việc dấu mũ trỏ tới đúng ký tự gây ra lỗi. Bạn có thể xóa xổ lỗi này bằng cách chuyển sang sử dụng ":".

Hơn nữa, các keyword argument trong định nghĩa hàm và gọi hàm cũng cần phải đúng vị trí. Keyword argument luôn đến sau các positional argument:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
6

Ở đây, một lần nữa, tin nhắn lỗi lại rất hữu ích khi nói chỉ rõ cho bạn thấy vị trí lỗi.

Changing Python Versions

Thi thoảng, code chạy tốt ở một phiên bản Python nhưng lại bị lỗi ở các version mới hơn. Điều này là vì những thay đổi trong cú pháp ngôn ngữ. Ví dụ điển hình nhất chính là lệnh

>>> pass = True
  File "", line 1
    pass = True
         ^
SyntaxError: invalid syntax

>>> def pass():
  File "", line 1
    def pass():
           ^
SyntaxError: invalid syntax
4 khi nó chuyển mình từ một keyword trong Python 2 thành một hàm built-in trong Python 3:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
7

Đây là một trong các ví dụ mà tin nhắn lỗi cho

>>> len('hello') == 5
True
1 được đưa ra có ý nghĩa nhất! Không chỉ nói cho bạn biết là bạn đang thiếu các dấu ngoặc đơn mà còn đưa ra giải pháp cho bạn.

Một vấn đề khác bạn có thể gặp chính là khi bạn đọc hoặc học về các cú pháp hợp lệ trong phiên bản mới hơn nhưng lại không hợp lệ trong phiên bản mà bạn đang dùng. Một ví dụ của việc này chính là cú pháp f-string - nó chỉ tồn tại trong các phiên bản từ 3.7 trở về sau:

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
8

Trong các phiên bản Python trước 3.6, trình biên dịch không hề hiểu gì về f-string và sẽ chỉ đưa ra một thông báo chung chung là "invalid syntax". Trong trường hợp này, vấn đề là code trông thì rất ổn nhưng nó lại được chạy với Python phiên bản cũ.

Cú pháp Python đang tiếp tục thay đổi, do đó sẽ có những tính năng mới được giới thiệu trong Python 3.8:

  • Walrus operator (assignment expressions)
  • F-string syntax for debugging
  • Positional-only arguments

Nếu bạn muốn thử các tính năng mới này thì bạn hãy chắc chắn rằng mình sử dụng môi trường Python 3.8. Nếu không thì bạn sẽ gặp lỗi

>>> len('hello') == 5
True
1.

Python 3.8 cũng cung cấp

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
16 mới. Bạn sẽ thấy cảnh báo này trong các trường hợp mà cú pháp hợp lệ nhưng vẫn có chút nghi ngờ. Ví dụ như khi bạn thiếu dấu "," giữa hai tuple trong một list. Việc làm như vậy có thể là hợp lệ về mặt cú pháp trong các phiên bản Python trước 3.8, nhưng code sẽ raise lên lỗi
$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
17 bởi vì một tuple là không callable (không thể gọi):

>>> len('hello') = 5
  File "", line 1
SyntaxError: can't assign to function call

>>> 'foo' = 1
  File "", line 1
SyntaxError: can't assign to literal

>>> 1 = 'foo'
  File "", line 1
SyntaxError: can't assign to literal
9

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
17 này có nghĩa là bạn không thể gọi một tuple như với một hàm - điều mà trình biên dịch nghĩ bạn đang cố gắng làm.

Trong Python 3.8, đoạn code này sẽ vẫn raise lên lỗi

>>> len('hello') == 5
True
1 nhưng bây giờ bạn sẽ thấy một
$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
20 nói rằng bạn cần phải giải quyết vấn đề:

>>> len('hello') == 5
True
0

Lời nhắn kèm theo

$ python theofficefacts.py
File "theofficefacts.py", line 5
    'michael': 43
            ^
SyntaxError: invalid syntax
16 thậm chí còn chỉ cho bạn hướng giải quyết vấn đề!

Conclusion

Trong tutorial này, bạn đã thấy được các thông tin mà traceback của

>>> len('hello') == 5
True
1 cung cấp cho bạn. Bạn cũng đã thấy được các ví dụ về lỗi cú pháp và giải pháp cho chúng.

Khi viết code, bạn thử sử dụng một IDE hỗ trợ việc soát lỗi và cung cấp feedback hữu ích. Nếu bạn đưa những đoạn code này vào một trình IDE tốt, nó sẽ highlight các lỗi cú pháp cho bạn thấy.

Việc gặp lỗi cú pháp

>>> len('hello') == 5
True
1 khi bạn đang học Python có thể khiến bạn nản lòng nhưng bây giờ bạn đã hiểu được các tin nhắn từ traceback và các dạng lỗi cú pháp trong Python mà bạn có thể gặp. Lần say khi gặp một lỗi
>>> len('hello') == 5
True
1, bạn sẽ sửa lỗi đó nhanh hơn!

Nguồn: https://realpython.com/invalid-syntax-python/