Cách chính xác để xác định mã hóa mã nguồn Python


163

PEP 263 định nghĩa cách khai báo mã hóa mã nguồn Python.

Thông thường, 2 dòng đầu tiên của tệp Python nên bắt đầu bằng:

#!/usr/bin/python
# -*- coding: <encoding name> -*-

Nhưng tôi đã thấy rất nhiều tập tin bắt đầu bằng:

#!/usr/bin/python
# -*- encoding: <encoding name> -*-

=> mã hóa thay vì mã hóa .

Vì vậy, cách chính xác để khai báo mã hóa tập tin là gì?

Được mã hóa được cho phép vì regex được sử dụng là lười biếng? Hay nó chỉ là một hình thức khai báo mã hóa tập tin?

Tôi đang hỏi câu hỏi này vì PEP không nói về mã hóa , nó chỉ nói về mã hóa .


4
Nhân tiện, để linh hoạt hơn và tính di động, nên sử dụng #!/usr/bin/env pythonthay vì#!/usr/bin/python
glarrain

7
Tôi thích cách không có câu trả lời nào trên trang này có một ví dụ đơn giản, hoạt động để nói UTF8. StackOverly tốt nhất của nó.
aaa90210

2
Tôi chỉ muốn thêm rằng Python 3 đã thay đổi mã hóa mặc định từ asciithành UTF-8. So sánh: python 2.7 docs với python 3.7 docs . Điều này có nghĩa là bạn có thể bỏ qua mã hóa này một cách an toàn nếu bạn muốn chỉ định UTF-8.
gertvdijk

Câu trả lời:


161

Kiểm tra các tài liệu ở đây :

"Nếu một nhận xét trong dòng đầu tiên hoặc thứ hai của tập lệnh Python khớp với biểu thức thông thường coding[=:]\s*([-\w.]+), nhận xét này được xử lý như một tuyên bố mã hóa"

"Các hình thức được đề nghị của biểu thức này là

# -*- coding: <encoding-name> -*-

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. "

Vì vậy, bạn có thể đặt khá nhiều thứ trước phần "mã hóa", nhưng vẫn gắn bó với "mã hóa" (không có tiền tố) nếu bạn muốn tương thích 100% python-docs-khuyên dùng.

Cụ thể hơn, bạn cần sử dụng bất cứ thứ gì được Python nhận ra và phần mềm chỉnh sửa cụ thể mà bạn sử dụng (nếu nó cần / chấp nhận mọi thứ). Ví dụ, codingbiểu mẫu được GNU Emacs công nhận (không có trong hộp) nhưng không phải Vim (vâng, không có thỏa thuận chung, về cơ bản nó là một cuộc chiến tranh sân cỏ ).


10
Tại sao -*-?
Iulian Onofrei

10
Việc -*-đảm bảo rằng dòng được GNU Emacs nhận ra (một trình soạn thảo văn bản phổ biến với một số lập trình viên). Lưu ý rằng, trái với câu trả lời này, cả biểu mẫu Emacs và biểu mẫu Vim đều tương thích với đề xuất 100% python-docs (vì cả hai đều khớp với biểu thức chính quy - "khớp", theo quy ước lâu dài, có nghĩa là "khớp bất kỳ nơi nào trong chuỗi ", trái với API của Python).
martinjs

1
Các yêu cầu cụ thể của Emacs đối với các chỉ thị được nhúng được ghi lại tại gnu.org/software/emacs/manual/html_node/emacs/ . Tóm lại, định dạng cho phần bắt đầu của tệp là : <prefix>-*- var: value[; ...] -*-.
ivan_pozdeev

38

PEP 263:

dòng đầu tiên hoặc thứ hai phải khớp với biểu thức chính quy "mã hóa [: =] \ s * ([- \ w.] +)"

Vì vậy, "en mã hóa: UTF-8 " khớp.

PEP cung cấp một số ví dụ:

#!/usr/bin/python
# vim: set fileencoding=<encoding name> :

 

# This Python file uses the following encoding: utf-8
import os, sys

31

Chỉ cần sao chép dán bên dưới tuyên bố trên đầu chương trình của bạn. Nó sẽ giải quyết các vấn đề mã hóa ký tự

#!/usr/bin/env python
# -*- coding: utf-8 -*-

3

Tính đến hôm nay - tháng 6 năm 2018


Bản thân PEP đề cập đến regex sau:

Để xác định mã hóa mã nguồn, một chú thích ma thuật phải được đặt vào các tệp nguồn là dòng đầu tiên hoặc thứ hai trong tệp, chẳng hạn như:

# coding=<encoding name>

hoặc (sử dụng các định dạng được công nhận bởi các biên tập viên phổ biến):

#!/usr/bin/python
# -*- coding: <encoding name> -*-

hoặc là:

#!/usr/bin/python
# vim: set fileencoding=<encoding name> : 

Chính xác hơn, dòng đầu tiên hoặc thứ hai phải khớp với biểu thức chính quy sau:

^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)

Vì vậy, như đã được tóm tắt bởi các câu trả lời khác, nó sẽ khớp codingvới bất kỳ tiền tố nào, nhưng nếu bạn muốn tuân thủ PEP như nó nhận được (mặc dù, theo như tôi có thể nói, sử dụng encodingthay vì codingkhông vi phạm PEP 263 theo bất kỳ cách nào) - gắn bó với 'đơn giản' coding, không có tiền tố.


1

Nếu tôi không nhầm, đề xuất ban đầu cho mã hóa tệp nguồn là sử dụng biểu thức chính quy cho một vài dòng đầu tiên, cho phép cả hai.

Tôi nghĩ rằng regex là một cái gì đó dọc theo dòng của coding:một cái gì đó theo sau.

Tôi đã tìm thấy điều này: http://www.python.org/dev/peps/pep-0263/ Đó là đề xuất ban đầu, nhưng dường như tôi không thể tìm thấy thông số cuối cùng nêu chính xác những gì họ đã làm.

Tôi chắc chắn đã sử dụng encoding:hiệu quả tuyệt vời, vì vậy rõ ràng là nó hoạt động.

Hãy thử thay đổi thành một cái gì đó hoàn toàn khác, muốn duhcoding: ...xem nó có hoạt động tốt không.


0

Tôi nghi ngờ nó tương tự như Ruby - một trong hai phương pháp đều ổn.

Điều này phần lớn là do các trình soạn thảo văn bản khác nhau sử dụng các phương pháp khác nhau (nghĩa là hai) mã hóa đánh dấu này.

Với Ruby, miễn là đầu tiên hoặc thứ hai nếu có một dòng shebang chứa một chuỗi khớp với:

coding: encoding-name

và bỏ qua bất kỳ khoảng trắng và lông tơ khác trên các dòng đó. (Nó thường có thể là a = thay vì :, quá).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.