email.header: Tiêu đề quốc tế hóa

Source code: Lib/email/header.py


Mô-đun này là một phần của email API cũ (Compat32). Trong mã hóa và giải mã API hiện tại của các tiêu đề được xử lý một cách minh bạch bởi API giống như từ điển của lớp EmailMessage. Ngoài việc sử dụng trong mã kế thừa, mô-đun này có thể hữu ích trong các ứng dụng cần kiểm soát hoàn toàn các bộ ký tự được sử dụng khi mã hóa tiêu đề.

Văn bản còn lại trong phần này là tài liệu gốc của mô-đun.

RFC 2822 là tiêu chuẩn cơ bản mô tả định dạng của email. Nó bắt nguồn từ tiêu chuẩn RFC 822 cũ hơn được sử dụng rộng rãi vào thời điểm mà hầu hết email chỉ bao gồm các ký tự ASCII. RFC 2822 là thông số kỹ thuật được viết giả sử email chỉ chứa các ký tự ASCII 7 bit.

Tất nhiên, vì email đã được triển khai trên toàn thế giới nên nó đã được quốc tế hóa, đến mức giờ đây các bộ ký tự dành riêng cho ngôn ngữ có thể được sử dụng trong email. Tiêu chuẩn cơ bản vẫn yêu cầu truyền email chỉ bằng các ký tự ASCII 7 bit, do đó, một loạt RFC đã được viết mô tả cách mã hóa email chứa các ký tự không phải ASCII thành định dạng tuân thủ RFC 2822-. Các RFC này bao gồm RFC 2045, RFC 2046, RFC 2047RFC 2231. Gói email hỗ trợ các tiêu chuẩn này trong các mô-đun email.headeremail.charset.

Nếu bạn muốn bao gồm các ký tự không phải ASCII trong tiêu đề email của mình, chẳng hạn như trong trường Subject hoặc To, bạn nên sử dụng lớp Header và gán trường trong đối tượng Message cho một phiên bản của Header thay vì sử dụng một chuỗi cho giá trị tiêu đề. Nhập lớp Header từ mô-đun email.header. Ví dụ:

>>> từ nhập email.message Tin nhắn
>>> từ tiêu đề nhập email.header
>>> tin nhắn = Tin nhắn()
>>> h = Tiêu đề('p\xf6stal', 'iso-8859-1')
>>> tin nhắn['Chủ đề'] = h
>>> tin nhắn.as_string()
'Chủ đề: =?iso-8859-1?q?p=F6stal?=\n\n'

Lưu ý ở đây chúng tôi muốn trường Subject chứa ký tự không phải ASCII như thế nào? Chúng tôi đã thực hiện điều này bằng cách tạo một phiên bản Header và chuyển vào bộ ký tự chứa chuỗi byte đã được mã hóa. Khi phiên bản Message tiếp theo được làm phẳng, trường Subject đã được mã hóa RFC 2047 chính xác. Trình đọc thư nhận biết MIME sẽ hiển thị tiêu đề này bằng cách sử dụng ký tự ISO-8859-1 được nhúng.

Đây là mô tả lớp Header:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

Tạo tiêu đề tuân thủ MIME có thể chứa các chuỗi trong các bộ ký tự khác nhau.

s tùy chọn là giá trị tiêu đề ban đầu. Nếu None (mặc định), giá trị tiêu đề ban đầu không được đặt. Sau này bạn có thể thêm vào tiêu đề bằng các lệnh gọi phương thức append(). s có thể là một phiên bản của bytes hoặc str, nhưng hãy xem tài liệu về append() để biết ngữ nghĩa.

charset tùy chọn phục vụ hai mục đích: nó có cùng ý nghĩa với đối số charset đối với phương thức append(). Nó cũng đặt bộ ký tự mặc định cho tất cả các lệnh gọi append() tiếp theo bỏ qua đối số charset. Nếu charset không được cung cấp trong hàm tạo (mặc định), bộ ký tự us-ascii được sử dụng làm bộ ký tự ban đầu của s và làm mặc định cho các lệnh gọi append() tiếp theo.

Độ dài dòng tối đa có thể được chỉ định rõ ràng thông qua maxlinelen. Để tách dòng đầu tiên thành giá trị ngắn hơn (để tính đến tiêu đề trường không có trong s, ví dụ: Subject), hãy chuyển tên của trường vào header_name. maxlinelen mặc định là 78 ​​và giá trị mặc định cho header_nameNone, nghĩa là nó không được tính đến dòng đầu tiên của một tiêu đề dài, phân tách.

continuation_ws tùy chọn phải là khoảng trắng gấp tương thích với RFC 2822- và thường là ký tự khoảng trắng hoặc ký tự tab cứng. Ký tự này sẽ được thêm vào các dòng tiếp theo. continuation_ws mặc định là một ký tự khoảng trắng.

errors tùy chọn được chuyển thẳng tới phương thức append().

append(s, charset=None, errors='strict')

Nối chuỗi s vào tiêu đề MIME.

charset tùy chọn, nếu được cung cấp, phải là phiên bản Charset (xem email.charset) hoặc tên của bộ ký tự, sẽ được chuyển đổi thành phiên bản Charset. Giá trị None (mặc định) có nghĩa là charset được cung cấp trong hàm tạo được sử dụng.

s có thể là một phiên bản của bytes hoặc str. Nếu đó là một phiên bản của bytes thì charset là mã hóa của chuỗi byte đó và UnicodeError sẽ được nâng lên nếu chuỗi không thể được giải mã bằng bộ ký tự đó.

Nếu s là một phiên bản của str thì charset là gợi ý chỉ định bộ ký tự của các ký tự trong chuỗi.

Trong cả hai trường hợp, khi tạo tiêu đề tuân thủ RFC 2822- bằng quy tắc RFC 2047, chuỗi sẽ được mã hóa bằng codec đầu ra của bộ ký tự. Nếu chuỗi không thể được mã hóa bằng codec đầu ra, UnicodeError sẽ xuất hiện.

errors tùy chọn được chuyển làm đối số lỗi cho lệnh gọi giải mã nếu s là một chuỗi byte.

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

Mã hóa tiêu đề thư thành định dạng tuân thủ RFC, có thể gói các dòng dài và đóng gói các phần không phải ASCII ở dạng mã hóa base64 hoặc có thể in được trong trích dẫn.

Zz002zz tùy chọn là một chuỗi chứa các ký tự cần được tăng thêm trọng số bằng thuật toán phân tách trong quá trình gói tiêu đề thông thường. Điều này hỗ trợ rất sơ bộ cho 'ngắt cú pháp cấp cao hơn' của RFC 2822: các điểm phân tách đứng trước dấu phân tách được ưu tiên trong quá trình phân tách dòng, với các ký tự được ưu tiên theo thứ tự chúng xuất hiện trong chuỗi. Dấu cách và tab có thể được bao gồm trong chuỗi để cho biết liệu có nên ưu tiên cái này hơn cái kia làm điểm phân tách khi các ký tự phân tách khác không xuất hiện trong dòng được phân tách hay không. Splitchars không ảnh hưởng đến các dòng được mã hóa RFC 2047.

maxlinelen, nếu được cung cấp, sẽ ghi đè giá trị của phiên bản đối với độ dài dòng tối đa.

linesep chỉ định các ký tự dùng để phân tách các dòng của phần đầu gấp lại. Nó mặc định có giá trị hữu ích nhất cho mã ứng dụng Python (\n), nhưng \r\n có thể được chỉ định để tạo các tiêu đề có dấu phân cách dòng tuân thủ RFC.

Thay đổi trong phiên bản 3.2: Đã thêm đối số linesep.

Lớp Header cũng cung cấp một số phương thức để hỗ trợ các toán tử tiêu chuẩn và các hàm dựng sẵn.

__str__()

Trả về giá trị gần đúng của Header dưới dạng một chuỗi, sử dụng độ dài dòng không giới hạn. Tất cả các phần được chuyển đổi sang unicode bằng cách sử dụng mã hóa được chỉ định và nối với nhau một cách thích hợp. Bất kỳ phần nào có bộ ký tự 'unknown-8bit' đều được giải mã thành ASCII bằng trình xử lý lỗi 'replace'.

Thay đổi trong phiên bản 3.2: Đã thêm xử lý cho bộ ký tự 'unknown-8bit'.

__eq__(other)

Phương pháp này cho phép bạn so sánh hai trường hợp Header về sự bằng nhau.

__ne__(other)

Phương pháp này cho phép bạn so sánh hai trường hợp Header về sự bất bình đẳng.

Mô-đun email.header cũng cung cấp các chức năng tiện lợi sau.

email.header.decode_header(header)

Giải mã giá trị tiêu đề thư mà không cần chuyển đổi bộ ký tự. Giá trị tiêu đề là header.

Vì lý do lịch sử, hàm này có thể trả về:

  1. Danh sách các cặp chứa từng phần được giải mã của tiêu đề, (decoded_bytes, charset), trong đó decoded_bytes luôn là một phiên bản của bytescharset là:

    • Một chuỗi chữ thường chứa tên của bộ ký tự được chỉ định.

    • None cho các phần không được mã hóa của tiêu đề.

  2. Danh sách có độ dài 1 chứa cặp (string, None), trong đó string luôn là một phiên bản của str.

Một email.errors.HeaderParseError có thể được tăng lên khi xảy ra một số lỗi giải mã nhất định (ví dụ: ngoại lệ giải mã base64).

Dưới đây là ví dụ:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
>>> decode_header('unencoded_string')
[('unencoded_string', None)]
>>> decode_header('bar =?utf-8?B?ZsOzbw==?=')
[(b'bar ', None), (b'f\xc3\xb3o', 'utf-8')]

Ghi chú

Chức năng này tồn tại chỉ để tương thích ngược. Đối với mã mới, chúng tôi khuyên bạn nên sử dụng email.headerregistry.HeaderRegistry.

email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

Tạo một phiên bản Header từ một chuỗi các cặp được trả về bởi decode_header().

decode_header() lấy chuỗi giá trị tiêu đề và trả về một chuỗi các cặp có định dạng (decoded_string, charset) trong đó charset là tên của bộ ký tự.

Hàm này lấy một trong các chuỗi cặp đó và trả về một phiên bản Header. maxlinelen, header_namecontinuation_ws tùy chọn giống như trong hàm tạo Header.

Ghi chú

Hàm này chỉ tồn tại để tương thích ngược và không được khuyến nghị sử dụng trong mã mới.