Có gì mới trong Python 2.3

tác giả:

A.M. Kuchling

Bài viết này giải thích các tính năng mới trong Python 2.3. Python 2.3 được phát hành vào ngày 29 tháng 7 năm 2003.

Các chủ đề chính của Python 2.3 là cải thiện một số tính năng được thêm vào trong 2.2, bổ sung nhiều cải tiến nhỏ nhưng hữu ích cho ngôn ngữ cốt lõi và mở rộng thư viện chuẩn. Mô hình đối tượng mới được giới thiệu trong phiên bản trước đã được hưởng lợi từ 18 tháng sửa lỗi và từ những nỗ lực tối ưu hóa đã cải thiện hiệu suất của các lớp kiểu mới. Một số chức năng tích hợp mới đã được thêm vào như sum()enumerate(). Toán tử in hiện có thể được sử dụng để tìm kiếm chuỗi con (ví dụ: "ab" in "abc" trả về True).

Một số trong nhiều tính năng mới của thư viện bao gồm các kiểu dữ liệu Boolean, tập hợp, vùng heap và ngày/giờ, khả năng nhập mô-đun từ kho lưu trữ định dạng ZIP, hỗ trợ siêu dữ liệu cho danh mục Python được chờ đợi từ lâu, phiên bản cập nhật của IDLE và các mô-đun để ghi nhật ký tin nhắn, gói văn bản, phân tích tệp CSV, xử lý các tùy chọn dòng lệnh, sử dụng cơ sở dữ liệu BerkeleyDB... danh sách các mô-đun mới và nâng cao còn dài.

Bài viết này không cố gắng cung cấp thông số kỹ thuật đầy đủ về các tính năng mới mà thay vào đó cung cấp một cái nhìn tổng quan thuận tiện. Để biết chi tiết đầy đủ, bạn nên tham khảo tài liệu dành cho Python 2.3, chẳng hạn như Python Library Reference và Python Reference Manual. Nếu bạn muốn hiểu cơ sở lý luận về thiết kế và triển khai đầy đủ, hãy tham khảo PEP để biết một tính năng mới cụ thể.

PEP 218: Kiểu dữ liệu tập hợp tiêu chuẩn

Mô-đun sets mới chứa phần triển khai kiểu dữ liệu đã đặt. Lớp Set dành cho các bộ có thể thay đổi, các bộ có thể thêm và xóa thành viên. Lớp ImmutableSet dành cho các bộ không thể sửa đổi và do đó, các phiên bản của ImmutableSet có thể được sử dụng làm khóa từ điển. Các bộ được xây dựng dựa trên từ điển, vì vậy các phần tử trong một bộ phải có thể băm được.

Đây là một ví dụ đơn giản:

>>> nhập bộ
>>> S = sets.Set([1,2,3])
>>> S
Đặt([1, 2, 3])
>>> 1 trong S
đúng
>>> 0 trong S
sai
>>> S.add(5)
>>> S.remove(3)
>>> S
Đặt([1, 2, 5])
>>>

Hợp và giao của các tập hợp có thể được tính bằng phương pháp union()intersection(); một ký hiệu thay thế sử dụng toán tử bitwise &|. Các bộ có thể thay đổi cũng có phiên bản tại chỗ của các phương thức này, union_update()intersection_update().

>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([4,5,6])
>>> S1.union(S2)
Đặt([1, 2, 3, 4, 5, 6])
>>> S1 |  hiệu S2 # Alternative
Đặt([1, 2, 3, 4, 5, 6])
>>> S1.intersection(S2)
Đặt([])
>>>  hiệu S1 & S2 # Alternative
Đặt([])
>>> S1.union_update(S2)
>>> S1
Đặt([1, 2, 3, 4, 5, 6])
>>>

Cũng có thể lấy hiệu đối xứng của hai tập hợp. Đây là tập hợp tất cả các phần tử trong hợp không nằm trong giao điểm. Một cách khác để diễn đạt là hiệu đối xứng chứa tất cả các phần tử nằm trong đúng một tập hợp. Một lần nữa, có một ký hiệu thay thế (^) và một phiên bản tại chỗ với cái tên vô duyên symmetric_difference_update().

>>> S1 = sets.Set([1,2,3,4])
>>> S2 = sets.Set([3,4,5,6])
>>> S1. đối xứng_difference(S2)
Đặt([1, 2, 5, 6])
>>> S1 ^ S2
Đặt([1, 2, 5, 6])
>>>

Ngoài ra còn có các phương pháp issubset()issuperset() để kiểm tra xem một tập hợp là tập hợp con hay tập hợp con của tập hợp khác:

>>> S1 = sets.Set([1,2,3])
>>> S2 = sets.Set([2,3])
>>> S2.issubset(S1)
đúng
>>> S1.issubset(S2)
sai
>>> S1.issuperset(S2)
đúng
>>>

Xem thêm

PEP 218 - Thêm loại đối tượng cài sẵn

PEP được viết bởi Greg V. Wilson. Được thực hiện bởi Greg V. Wilson, Alex Martelli và GvR.

PEP 255: Máy phát điện đơn giản

Trong Python 2.2, trình tạo đã được thêm dưới dạng tính năng tùy chọn, được kích hoạt bằng lệnh from __future__ import generators. Trong 2.3, trình tạo không cần phải được kích hoạt đặc biệt nữa và hiện luôn có mặt; điều này có nghĩa là yield hiện luôn là một từ khóa. Phần còn lại của phần này là bản sao mô tả của các trình tạo từ tài liệu "Có gì mới trong Python 2.2"; nếu bạn đọc lại khi Python 2.2 ra mắt, bạn có thể bỏ qua phần còn lại của phần này.

Bạn chắc chắn đã quen với cách hoạt động của các lệnh gọi hàm trong Python hoặc C. Khi bạn gọi một hàm, nó sẽ có một vùng tên riêng nơi các biến cục bộ của nó được tạo. Khi hàm đạt đến câu lệnh return, các biến cục bộ sẽ bị hủy và giá trị kết quả được trả về cho người gọi. Lệnh gọi sau đó tới hàm tương tự sẽ nhận được một tập hợp biến cục bộ mới. Tuy nhiên, điều gì sẽ xảy ra nếu các biến cục bộ không bị loại bỏ khi thoát khỏi hàm? Điều gì sẽ xảy ra nếu sau này bạn có thể tiếp tục lại chức năng mà nó đã dừng lại? Đây là những gì máy phát điện cung cấp; chúng có thể được coi là các chức năng có thể tiếp tục.

Đây là ví dụ đơn giản nhất về hàm tạo:

def tạo_ints (N):
    cho tôi trong phạm vi (N):
        nhường tôi

Một từ khóa mới, yield, đã được giới thiệu cho máy phát điện. Bất kỳ hàm nào chứa câu lệnh yield đều là hàm tạo; điều này được phát hiện bởi trình biên dịch mã byte của Python để biên dịch hàm một cách đặc biệt.

Khi bạn gọi một hàm tạo, nó không trả về một giá trị nào; thay vào đó nó trả về một đối tượng trình tạo hỗ trợ giao thức vòng lặp. Khi thực thi câu lệnh yield, trình tạo sẽ xuất ra giá trị của i, tương tự như câu lệnh return. Sự khác biệt lớn giữa câu lệnh yield và câu lệnh return là khi đạt tới yield, trạng thái thực thi của trình tạo bị tạm dừng và các biến cục bộ được giữ nguyên. Trong lệnh gọi tiếp theo tới phương thức .next() của trình tạo, hàm sẽ tiếp tục thực thi ngay sau câu lệnh yield. (Vì những lý do phức tạp, câu lệnh yield không được phép bên trong khối try của câu lệnh try...finally; hãy đọc PEP 255 để biết giải thích đầy đủ về sự tương tác giữa yield và các ngoại lệ.)

Đây là cách sử dụng mẫu của trình tạo generate_ints():

>>> gen = generate_ints(3)
>>> thế hệ
<đối tượng máy phát điện ở 0x8117f90>
>>> gen.next()
0
>>> gen.next()
1
>>> gen.next()
2
>>> gen.next()
Traceback (cuộc gọi gần đây nhất):
  Tệp "stdin", dòng 1, ở dạng ?
  Tệp "stdin", dòng 2, trong generate_ints
Dừng lại

Bạn cũng có thể viết for i in generate_ints(5) hoặc a,b,c = generate_ints(3).

Bên trong hàm tạo, câu lệnh return chỉ có thể được sử dụng mà không có giá trị và báo hiệu sự kết thúc của quá trình xử lý các giá trị; sau đó trình tạo không thể trả về bất kỳ giá trị nào nữa. return có giá trị, chẳng hạn như return 5, là lỗi cú pháp bên trong hàm tạo. Sự kết thúc của kết quả của trình tạo cũng có thể được biểu thị bằng cách tăng StopIteration theo cách thủ công hoặc chỉ bằng cách để luồng thực thi rơi ra khỏi phần dưới cùng của hàm.

Bạn có thể đạt được hiệu quả của trình tạo theo cách thủ công bằng cách viết lớp của riêng bạn và lưu trữ tất cả các biến cục bộ của trình tạo dưới dạng biến thể hiện. Ví dụ: việc trả về một danh sách các số nguyên có thể được thực hiện bằng cách đặt self.count thành 0 và để phương thức next() tăng self.count rồi trả về nó. Tuy nhiên, đối với một trình tạo có độ phức tạp vừa phải, việc viết một lớp tương ứng sẽ rắc rối hơn nhiều. Lib/test/test_generators.py chứa một số ví dụ thú vị hơn. Cách đơn giản nhất là thực hiện duyệt cây theo thứ tự bằng cách sử dụng các trình tạo đệ quy.

Trình tạo đệ quy # A tạo ra các lá Cây theo thứ tự.
thứ tự def (t):
    nếu t:
        cho x theo thứ tự (t.left):
            năng suất x
        năng suất t.label
        cho x theo thứ tự (t.right):
            năng suất x

Hai ví dụ khác trong Lib/test/test_generators.py đưa ra giải pháp cho bài toán N-Queens (đặt các quân hậu $N$ trên bàn cờ $NxN$ để không có quân hậu nào đe dọa quân hậu khác) và Chuyến tham quan của Hiệp sĩ (một lộ trình đưa một quân mã đến mọi ô của bàn cờ $NxN$ mà không ghé thăm bất kỳ ô nào hai lần).

Ý tưởng về trình tạo xuất phát từ các ngôn ngữ lập trình khác, đặc biệt là Icon (https://www2.cs.arizona.edu/icon/), trong đó ý tưởng về trình tạo là trung tâm. Trong Icon, mọi lệnh gọi biểu thức và hàm hoạt động giống như một trình tạo. Một ví dụ từ "Tổng quan về Ngôn ngữ lập trình biểu tượng" tại https://www2.cs.arizona.edu/icon/docs/ipd266.htm đưa ra ý tưởng về giao diện này:

câu := "Cất nó ở bến cảng lân cận"
if (i := find("hoặc", câu)) > 5 thì viết(i)

Trong Icon, hàm find() trả về các chỉ mục tại đó tìm thấy chuỗi con "hoặc": 3, 23, 33. Trong câu lệnh if, i trước tiên được gán giá trị là 3, nhưng 3 nhỏ hơn 5, do đó so sánh không thành công và Icon thử lại với giá trị thứ hai là 23. 23 lớn hơn 5, do đó, phép so sánh bây giờ thành công và mã in giá trị 23 thành giá trị 23. màn hình.

Python không tiến xa được như Icon trong việc áp dụng máy phát điện làm khái niệm trung tâm. Trình tạo được coi là một phần của ngôn ngữ Python cốt lõi, nhưng việc học hoặc sử dụng chúng không bắt buộc; nếu chúng không giải quyết được bất kỳ vấn đề nào bạn gặp phải, hãy bỏ qua chúng. Một tính năng mới của giao diện Python so với Icon là trạng thái của trình tạo được biểu diễn dưới dạng một đối tượng cụ thể (trình vòng lặp) có thể được chuyển sang các hàm khác hoặc được lưu trữ trong cấu trúc dữ liệu.

Xem thêm

PEP 255 - Máy phát điện đơn giản

Viết bởi Neil Schenauer, Tim Peters, Magnus Lie Hetland. Được triển khai chủ yếu bởi Neil Schenauer và Tim Peters, cùng với các bản sửa lỗi khác từ nhóm Python Labs.

PEP 263: Mã hóa mã nguồn

Giờ đây, các tệp nguồn Python có thể được khai báo ở các mã hóa bộ ký tự khác nhau. Mã hóa được khai báo bằng cách đưa nhận xét có định dạng đặc biệt vào dòng đầu tiên hoặc dòng thứ hai của tệp nguồn. Ví dụ: tệp UTF-8 có thể được khai báo bằng

#!/usr/bin/env trăn
# -zz000zz-

Nếu không có khai báo mã hóa như vậy thì mã hóa mặc định được sử dụng là ASCII 7 bit. Việc thực thi hoặc nhập các mô-đun chứa chuỗi ký tự có ký tự 8 bit và không có khai báo mã hóa sẽ dẫn đến việc DeprecationWarning được Python 2.3 báo hiệu; trong phiên bản 2.4 đây sẽ là lỗi cú pháp.

Khai báo mã hóa chỉ ảnh hưởng đến các chuỗi ký tự Unicode, các chuỗi này sẽ được chuyển đổi sang Unicode bằng cách sử dụng mã hóa được chỉ định. Lưu ý rằng mã định danh Python vẫn bị giới hạn ở các ký tự ASCII, vì vậy bạn không thể có tên biến sử dụng các ký tự bên ngoài chữ và số thông thường.

Xem thêm

PEP 263 - Xác định mã hóa mã nguồn Python

Viết bởi Marc-André Lemburg và Martin von Löwis; được thực hiện bởi Suzuki Hisao và Martin von Löwis.

PEP 273: Nhập mô-đun từ kho lưu trữ ZIP

Mô-đun zipimport mới bổ sung hỗ trợ nhập mô-đun từ kho lưu trữ có định dạng ZIP. Bạn không cần nhập mô-đun một cách rõ ràng; nó sẽ được nhập tự động nếu tên tệp của kho lưu trữ ZIP được thêm vào sys.path. Ví dụ:

amk@nyman:~/src/python$ giải nén -l /tmp/example.zip
Lưu trữ: /tmp/example.zip
  Độ dài Ngày Giờ Tên
 -------- ---- ---- ----
     8467 26-11-02 22:30 jwzthreading.py
 -------- -------
     8467 1 tập tin
amk@nyman:~/src/python$ ./python
Python 2.3 (#1, ngày 1 tháng 8 năm 2003, 19:54:32)
>>> nhập hệ thống
>>> sys.path.insert(0, '/tmp/example.zip') tệp # Add .zip ở phía trước đường dẫn
>>> nhập jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'
>>>

Một mục trong sys.path hiện có thể là tên tệp của kho lưu trữ ZIP. Kho lưu trữ ZIP có thể chứa bất kỳ loại tệp nào nhưng chỉ có thể nhập các tệp có tên *.py, *.pyc hoặc *.pyo. Nếu kho lưu trữ chỉ chứa các tệp *.py, Python sẽ không cố gắng sửa đổi kho lưu trữ bằng cách thêm tệp *.pyc tương ứng, nghĩa là nếu kho lưu trữ ZIP không chứa các tệp *.pyc thì quá trình nhập có thể khá chậm.

Một đường dẫn trong kho lưu trữ cũng có thể được chỉ định để chỉ nhập từ thư mục con; ví dụ: đường dẫn /tmp/example.zip/lib/ sẽ chỉ nhập từ thư mục con lib/ trong kho lưu trữ.

Xem thêm

PEP 273 - Nhập mô-đun từ kho lưu trữ Zip

Được viết bởi James C. Ahlstrom, người cũng cung cấp cách triển khai. Python 2.3 tuân theo đặc tả trong PEP 273, nhưng sử dụng cách triển khai được viết bởi Just van Rossum và sử dụng các móc nhập được mô tả trong PEP 302. Xem phần PEP 302: Móc nhập khẩu mới để biết mô tả về các hook nhập mới.

PEP 277: Hỗ trợ tên tệp Unicode cho Windows NT

Trên Windows NT, 2000 và XP, hệ thống lưu trữ tên tệp dưới dạng chuỗi Unicode. Theo truyền thống, Python biểu diễn tên tệp dưới dạng chuỗi byte, điều này là không đủ vì nó khiến một số tên tệp không thể truy cập được.

Python hiện cho phép sử dụng các chuỗi Unicode tùy ý (trong giới hạn của hệ thống tệp) cho tất cả các hàm yêu cầu tên tệp, đáng chú ý nhất là hàm tích hợp open(). Nếu một chuỗi Unicode được chuyển tới os.listdir(), Python hiện trả về danh sách các chuỗi Unicode. Một hàm mới, os.getcwdu(), trả về thư mục hiện tại dưới dạng chuỗi Unicode.

Chuỗi byte vẫn hoạt động như tên tệp và trên Windows Python sẽ chuyển đổi chúng sang Unicode một cách trong suốt bằng cách sử dụng mã hóa mbcs.

Các hệ thống khác cũng cho phép chuỗi Unicode làm tên tệp nhưng chuyển đổi chúng thành chuỗi byte trước khi chuyển chúng sang hệ thống, điều này có thể khiến UnicodeError được nâng lên. Các ứng dụng có thể kiểm tra xem các chuỗi Unicode tùy ý có được hỗ trợ dưới dạng tên tệp hay không bằng cách kiểm tra os.path.supports_unicode_filenames, một giá trị Boolean.

Trong MacOS, os.listdir() hiện có thể trả về tên tệp Unicode.

Xem thêm

PEP 277 - Hỗ trợ tên tệp Unicode cho Windows NT

Viết bởi Neil Hodgson; được thực hiện bởi Neil Hodgson, Martin von Löwis và Mark Hammond.

PEP 278: Hỗ trợ dòng mới toàn cầu

Ba hệ điều hành chính được sử dụng ngày nay là Microsoft Windows, Macintosh OS của Apple và các dẫn xuất Unix khác nhau. Một điều khó chịu nhỏ khi làm việc trên nhiều nền tảng là ba nền tảng này đều sử dụng các ký tự khác nhau để đánh dấu phần cuối dòng trong tệp văn bản. Unix sử dụng nguồn cấp dữ liệu (ký tự ASCII 10), MacOS sử dụng dấu xuống dòng (ký tự ASCII 13) và Windows sử dụng chuỗi hai ký tự của dấu xuống dòng cộng với một dòng mới.

Các đối tượng tệp của Python giờ đây có thể hỗ trợ các quy ước cuối dòng khác với quy ước được theo sau bởi nền tảng mà Python đang chạy. Mở tệp có chế độ 'U' hoặc 'rU' sẽ mở tệp để đọc ở chế độ universal newlines. Tất cả ba quy ước kết thúc dòng sẽ được dịch sang '\n' trong chuỗi được trả về bằng các phương thức tệp khác nhau như read()readline().

Hỗ trợ dòng mới phổ quát cũng được sử dụng khi nhập mô-đun và khi thực thi tệp có chức năng execfile(). Điều này có nghĩa là các mô-đun Python có thể được chia sẻ giữa cả ba hệ điều hành mà không cần chuyển đổi phần cuối dòng.

Tính năng này có thể bị tắt khi biên dịch Python bằng cách chỉ định khóa chuyển --without-universal-newlines khi chạy tập lệnh configure của Python.

Xem thêm

PEP 278 - Hỗ trợ dòng mới toàn cầu

Được viết và thực hiện bởi Jack Jansen.

PEP 279: liệt kê()

Một chức năng tích hợp mới, enumerate(), sẽ làm cho một số vòng lặp nhất định rõ ràng hơn một chút. enumerate(thing), trong đó thing là một trình vòng lặp hoặc một chuỗi, trả về một trình vòng lặp sẽ trả về (0, thing[0]), (1, thing[1]), (2, thing[2]), v.v.

Một thành ngữ phổ biến để thay đổi mọi thành phần của danh sách trông như thế này

cho tôi trong phạm vi(len(L)):
    mục = L[i]
    # ... tính toán một số kết quả dựa trên mục ...
    L[i] = kết quả

Điều này có thể được viết lại bằng enumerate() như:

đối với i, mục trong liệt  (L):
    # ... tính toán một số kết quả dựa trên mục ...
    L[i] = kết quả

Xem thêm

PEP 279 - Hàm tích hợp enumerate()

Được viết và thực hiện bởi Raymond D. Hettinger.

PEP 282: Gói ghi nhật ký

Gói tiêu chuẩn để ghi nhật ký, logging, đã được thêm vào Python 2.3. Nó cung cấp một cơ chế mạnh mẽ và linh hoạt để tạo đầu ra ghi nhật ký, sau đó có thể được lọc và xử lý theo nhiều cách khác nhau. Tệp cấu hình được viết ở định dạng chuẩn có thể được sử dụng để kiểm soát hành vi ghi nhật ký của chương trình. Python bao gồm các trình xử lý sẽ ghi các bản ghi nhật ký vào lỗi tiêu chuẩn hoặc vào một tệp hoặc ổ cắm, gửi chúng đến nhật ký hệ thống hoặc thậm chí gửi chúng qua e-mail đến một địa chỉ cụ thể; tất nhiên, bạn cũng có thể viết các lớp xử lý của riêng mình.

Lớp Logger là lớp chính. Hầu hết mã ứng dụng sẽ xử lý một hoặc nhiều đối tượng Logger, mỗi đối tượng được sử dụng bởi một hệ thống con cụ thể của ứng dụng. Mỗi Logger được xác định bằng một tên và các tên được sắp xếp thành một hệ thống phân cấp sử dụng . làm dấu phân cách thành phần. Ví dụ: bạn có thể có các phiên bản Logger có tên là server, server.authserver.network. Hai trường hợp sau nằm dưới server trong hệ thống phân cấp. Điều này có nghĩa là nếu bạn tăng mức độ chi tiết cho server hoặc gửi tin nhắn server trực tiếp đến một trình xử lý khác thì những thay đổi cũng sẽ áp dụng cho các bản ghi được ghi vào server.authserver.network. Ngoài ra còn có một Logger gốc là nguồn gốc của tất cả các trình ghi nhật ký khác.

Để sử dụng đơn giản, gói logging chứa một số chức năng tiện lợi luôn sử dụng nhật ký gốc

nhập nhật 

logging.debug('Thông tin gỡ lỗi')
logging.info('Thông báo thông tin')
logging.warning('Cảnh báo:không tìm thấy tập tin cấu hình %s', 'server.conf')
logging.error('Đã xảy ra lỗi')
logging.cript('Lỗi nghiêm trọng -- đang tắt')

Điều này tạo ra đầu ra sau:

WARNING:root:Cảnh báo:không tìm thấy tệp cấu hình server.conf
ERROR:root:Đã xảy ra lỗi
CRITICAL:root:Lỗi nghiêm trọng -- đang tắt

Trong cấu hình mặc định, các thông báo thông tin và gỡ lỗi bị chặn và đầu ra được gửi tới lỗi tiêu chuẩn. Bạn có thể kích hoạt hiển thị thông báo thông tin và gỡ lỗi bằng cách gọi phương thức setLevel() trên trình ghi nhật ký gốc.

Lưu ý việc sử dụng toán tử định dạng chuỗi của lệnh gọi warning(); tất cả các hàm ghi nhật ký thông báo đều lấy các đối số (msg, arg1, arg2, ...) và ghi lại chuỗi kết quả từ msg % (arg1, arg2, ...).

Ngoài ra còn có chức năng exception() ghi lại dấu vết gần đây nhất. Bất kỳ hàm nào khác cũng sẽ ghi lại dấu vết nếu bạn chỉ định giá trị thực cho đối số từ khóa exc_info.

chắc chắn f():
    thử: 1/0
    ngoại trừ: log.Exception('Sự cố đã được ghi lại')

f()

Điều này tạo ra đầu ra sau:

ERROR:root:Đã ghi lại sự cố
Traceback (cuộc gọi gần đây nhất):
  Tệp "t.py", dòng 6, trong f
    1/0
ZeroDivisionError: chia số nguyên hoặc modulo cho 0

Các chương trình nâng cao hơn một chút sẽ sử dụng một trình ghi nhật ký khác với trình ghi nhật ký gốc. Hàm getLogger(name) được sử dụng để lấy một nhật ký cụ thể, tạo nhật ký đó nếu nó chưa tồn tại. getLogger(None) trả về trình ghi nhật ký gốc.

log = log.getLogger('server')
 ...
log.info('Nghe trên cổng %i', port)
 ...
log.cript('Đĩa đầy')
 ...

Các bản ghi nhật ký thường được truyền lên theo hệ thống phân cấp, do đó, một thông báo được ghi vào server.auth cũng được serverroot nhìn thấy, nhưng Logger có thể ngăn chặn điều này bằng cách đặt thuộc tính propagate của nó thành False.

Có nhiều lớp hơn được cung cấp bởi gói logging có thể được tùy chỉnh. Khi một phiên bản Logger được yêu cầu ghi nhật ký một tin nhắn, nó sẽ tạo một phiên bản LogRecord được gửi đến bất kỳ phiên bản Handler nào khác nhau. Trình ghi nhật ký và trình xử lý cũng có thể có danh sách bộ lọc đính kèm và mỗi bộ lọc có thể khiến LogRecord bị bỏ qua hoặc có thể sửa đổi bản ghi trước khi chuyển nó. Cuối cùng khi chúng được xuất ra, các phiên bản LogRecord được lớp Formatter chuyển đổi thành văn bản. Tất cả các lớp này có thể được thay thế bằng các lớp được viết đặc biệt của riêng bạn.

Với tất cả các tính năng này, gói logging sẽ cung cấp đủ tính linh hoạt cho cả những ứng dụng phức tạp nhất. Đây chỉ là phần tổng quan chưa đầy đủ về các tính năng của gói, vì vậy vui lòng xem tài liệu tham khảo của gói để biết tất cả chi tiết. Đọc PEP 282 cũng sẽ hữu ích.

Xem thêm

PEP 282 - Hệ thống ghi nhật ký

Viết bởi Vinay Sajip và Trent Mick; do Vinay Sajip thực hiện.

PEP 285: Loại Boolean

Loại Boolean đã được thêm vào Python 2.3. Hai hằng số mới đã được thêm vào mô-đun __builtin__, TrueFalse. (Hằng số TrueFalse đã được thêm vào các phần dựng sẵn trong Python 2.2.1, nhưng các phiên bản 2.2.1 chỉ được đặt thành giá trị nguyên là 1 và 0 và không phải là một loại khác.)

Đối tượng kiểu cho kiểu mới này được đặt tên là bool; hàm tạo của nó nhận bất kỳ giá trị Python nào và chuyển đổi nó thành True hoặc False.

>>> bool(1)
đúng
>>> bool(0)
sai
>>> bool([])
sai
>>> bool( (1,) )
đúng

Hầu hết các mô-đun thư viện tiêu chuẩn và các hàm dựng sẵn đã được thay đổi để trả về Booleans.

>>> obj = []
>>> hasattr(obj, 'nối thêm')
đúng
>>> isinstance(obj, list)
đúng
>>> isinstance(obj, tuple)
sai

Booleans của Python đã được thêm vào với mục tiêu chính là làm cho mã rõ ràng hơn. Ví dụ: nếu bạn đang đọc một hàm và gặp câu lệnh return 1, bạn có thể thắc mắc liệu 1 có đại diện cho giá trị chân lý Boolean, một chỉ số hay một hệ số nhân một số đại lượng khác hay không. Tuy nhiên, nếu câu lệnh là return True thì ý nghĩa của giá trị trả về khá rõ ràng.

Booleans của Python đã được thêm vào not để kiểm tra kiểu nghiêm ngặt. Một ngôn ngữ rất nghiêm ngặt như Pascal cũng sẽ ngăn bạn thực hiện phép tính với Boolean và sẽ yêu cầu biểu thức trong câu lệnh if luôn đánh giá thành kết quả Boolean. Python không nghiêm ngặt đến mức này và sẽ không bao giờ như vậy, như PEP 285 đã nói rõ ràng. Điều này có nghĩa là bạn vẫn có thể sử dụng bất kỳ biểu thức nào trong câu lệnh if, ngay cả những biểu thức đánh giá một danh sách, bộ dữ liệu hoặc một số đối tượng ngẫu nhiên. Kiểu Boolean là một lớp con của lớp int để số học sử dụng Boolean vẫn hoạt động.

>>> Đúng + 1
2
>>> Sai + 1
1
>>> Sai * 75
0
>>> Đúng * 75
75

Tóm tắt TrueFalse trong một câu: chúng là những cách khác để đánh vần các giá trị số nguyên 1 và 0, với điểm khác biệt duy nhất là str()repr() trả về các chuỗi 'True''False' thay vì '1''0'.

Xem thêm

PEP 285 - Thêm loại bool

Được viết và thực hiện bởi GvR.

PEP 293: Lệnh gọi lại xử lý lỗi Codec

Khi mã hóa chuỗi Unicode thành chuỗi byte, có thể gặp phải các ký tự không thể mã hóa. Cho đến nay, Python đã cho phép chỉ định việc xử lý lỗi là "nghiêm ngặt" (tăng UnicodeError), "bỏ qua" (bỏ qua ký tự) hoặc "thay thế" (sử dụng dấu chấm hỏi trong chuỗi đầu ra), với "nghiêm ngặt" là hành vi mặc định. Có thể nên chỉ định cách xử lý thay thế cho các lỗi như vậy, chẳng hạn như chèn tham chiếu ký tự XML hoặc tham chiếu thực thể HTML vào chuỗi được chuyển đổi.

Python hiện có một khung linh hoạt để thêm các chiến lược xử lý khác nhau. Trình xử lý lỗi mới có thể được thêm bằng codecs.register_error() và sau đó các codec có thể truy cập trình xử lý lỗi bằng codecs.lookup_error(). Một C API tương đương đã được thêm vào cho các codec được viết bằng C. Trình xử lý lỗi nhận được thông tin trạng thái cần thiết như chuỗi đang được chuyển đổi, vị trí trong chuỗi nơi phát hiện lỗi và mã hóa mục tiêu. Sau đó, trình xử lý có thể đưa ra một ngoại lệ hoặc trả về một chuỗi thay thế.

Hai trình xử lý lỗi bổ sung đã được triển khai bằng khung này: "backslashreplace" sử dụng trích dẫn dấu gạch chéo ngược của Python để biểu thị các ký tự không thể mã hóa và "xmlcharrefreplace" phát ra các tham chiếu ký tự XML.

Xem thêm

PEP 293 - Lệnh gọi lại xử lý lỗi Codec

Được viết và thực hiện bởi Walter Dörwald.

PEP 301: Chỉ mục gói và siêu dữ liệu cho Distutils

Hỗ trợ cho danh mục Python được yêu cầu từ lâu đã xuất hiện lần đầu tiên trong phiên bản 2.3.

Trọng tâm của danh mục là lệnh Distutils register mới. Chạy python setup.py register sẽ thu thập siêu dữ liệu mô tả một gói, chẳng hạn như tên, phiên bản, nhà bảo trì, mô tả, &c., và gửi nó đến máy chủ danh mục trung tâm. Danh mục kết quả có sẵn từ https://pypi.org.

Để làm cho danh mục trở nên hữu ích hơn một chút, một đối số từ khóa classifiers tùy chọn mới đã được thêm vào hàm Distutils setup(). Danh sách các chuỗi kiểu Trove có thể được cung cấp để giúp phân loại phần mềm.

Đây là một ví dụ setup.py với các bộ phân loại, được viết để tương thích với các phiên bản cũ hơn của Distutils:

từ lõi nhập khẩu distutils
kw = {'name': "Quixote",
      'phiên bản': "0.5.1",
      'description': "Một khung ứng dụng Web có tính Pythonic cao",
      # ...
      }

if (hasattr(core, 'setup_keywords') 
    'bộ phân loại' trong core.setup_keywords):
    kw['phân loại'] = \
        ['Chủ đề :: Internet :: WWW/HTTP :: Nội dung động',
         'Môi trường :: Không có đầu vào/đầu ra (Daemon)',
         'Đối tượng dự kiến :: Nhà phát triển'],

core.setup(**kw)

Danh sách đầy đủ các bộ phân loại có thể được lấy bằng cách chạy python setup.py register --list-classifiers.

Xem thêm

PEP 301 - Chỉ mục gói và siêu dữ liệu cho Distutils

Được viết và thực hiện bởi Richard Jones.

PEP 302: Móc nhập khẩu mới

Mặc dù có thể viết các hook nhập tùy chỉnh kể từ khi mô-đun ihooks được giới thiệu trong Python 1.3, nhưng chưa có ai thực sự hài lòng với nó vì việc viết các hook nhập mới rất khó và lộn xộn. Đã có nhiều lựa chọn thay thế được đề xuất khác nhau, chẳng hạn như mô-đun imputiliu, nhưng không có mô-đun nào trong số chúng nhận được nhiều sự chấp nhận và không có mô-đun nào trong số chúng có thể dễ dàng sử dụng được từ mã C.

PEP 302 mượn ý tưởng từ những người tiền nhiệm, đặc biệt là từ mô-đun iu của Gordon McMillan. Ba mục mới được thêm vào mô-đun sys:

  • sys.path_hooks là danh sách các đối tượng có thể gọi được; thường thì họ sẽ là các lớp học. Mỗi lệnh gọi có thể nhận một chuỗi chứa một đường dẫn và trả về một đối tượng nhập sẽ xử lý việc nhập từ đường dẫn này hoặc đưa ra một ngoại lệ ImportError nếu nó không thể xử lý đường dẫn này.

  • sys.path_importer_cache lưu trữ các đối tượng nhập khẩu cho mỗi đường dẫn, vì vậy sys.path_hooks sẽ chỉ cần duyệt một lần cho mỗi đường dẫn.

  • sys.meta_path là danh sách các đối tượng nhập khẩu sẽ được duyệt qua trước khi sys.path được kiểm tra. Danh sách này ban đầu trống nhưng mã người dùng có thể thêm đối tượng vào đó. Các mô-đun tích hợp và cố định bổ sung có thể được nhập bởi một đối tượng được thêm vào danh sách này.

Các đối tượng nhập khẩu phải có một phương thức duy nhất, find_module(fullname, path=None). fullname sẽ là tên mô-đun hoặc gói, ví dụ: string hoặc distutils.core. find_module() phải trả về một đối tượng trình tải có một phương thức duy nhất, load_module(fullname), để tạo và trả về đối tượng mô-đun tương ứng.

Do đó, mã giả cho logic nhập mới của Python trông giống như thế này (đơn giản hóa một chút; xem PEP 302 để biết chi tiết đầy đủ):

cho mp trong sys.meta_path:
    trình tải = mp(tên đầy đủ)
    nếu trình tải không phải  Không :
        <-đun> = Loader.load_module(tên đầy đủ)

cho đường dẫn trong sys.path:
    cho hook trong sys.path_hooks:
        thử:
            nhà nhập khẩu = hook(path)
        ngoại trừ lỗi nhập khẩu:
            # ImportError, vậy hãy thử các hook đường dẫn khác
            vượt qua
        khác:
            bộ nạp = import.find_module(fullname)
            <-đun> = Loader.load_module(tên đầy đủ)

đã tìm thấy # Not!
tăng lỗi nhập khẩu

Xem thêm

PEP 302 - Móc nhập khẩu mới

Viết bởi Just van Rossum và Paul Moore. Được thực hiện bởi Just van Rossum.

PEP 305: Tệp được phân tách bằng dấu phẩy

Các tệp được phân tách bằng dấu phẩy là định dạng thường được sử dụng để xuất dữ liệu từ cơ sở dữ liệu và bảng tính. Python 2.3 thêm trình phân tích cú pháp cho các tệp được phân tách bằng dấu phẩy.

Định dạng được phân tách bằng dấu phẩy thoạt nhìn có vẻ đơn giản:

Chi phí, 150.200,3,95

Đọc một dòng và gọi line.split(','): điều gì có thể đơn giản hơn? Nhưng việc đưa vào dữ liệu chuỗi có thể chứa dấu phẩy và mọi thứ trở nên phức tạp hơn

"Chi phí",150.200,3,95,"Bao gồm thuế, vận chuyển và các mặt hàng lặt vặt"

Một biểu thức chính quy to lớn và xấu xí có thể phân tích cú pháp này, nhưng việc sử dụng gói csv mới đơn giản hơn nhiều:

nhập csv

đầu vào = open('datafile', 'rb')
reader = csv.reader(đầu vào)
cho dòng trong đầu đọc:
    dòng in

Hàm reader() có một số tùy chọn khác nhau. Dấu phân cách trường không bị giới hạn ở dấu phẩy và có thể được thay đổi thành bất kỳ ký tự nào, cũng như các ký tự trích dẫn và kết thúc dòng cũng vậy.

Có thể xác định và đăng ký các phương ngữ khác nhau của các tệp được phân tách bằng dấu phẩy; hiện tại có hai phương ngữ, cả hai đều được Microsoft Excel sử dụng. Một lớp csv.writer riêng biệt sẽ tạo ra các tệp được phân tách bằng dấu phẩy từ một chuỗi các bộ dữ liệu hoặc danh sách, trích dẫn các chuỗi có chứa dấu phân cách.

Xem thêm

PEP 305 - CSV Tập tin API

Được viết và thực hiện bởi Kevin Altis, Dave Cole, Andrew McNamara, Skip Montanaro, Cliff Wells.

PEP 307: Cải tiến dưa chua

Các mô-đun picklecPickle đã nhận được một số sự chú ý trong chu kỳ phát triển 2.3. Trong 2.2, các lớp kiểu mới có thể được tích hợp mà không gặp khó khăn gì, nhưng chúng không được tích hợp chặt chẽ; PEP 307 trích dẫn một ví dụ tầm thường trong đó một lớp kiểu mới tạo ra một chuỗi được ngâm dài hơn ba lần so với một lớp cổ điển.

Giải pháp là phát minh ra một giao thức dưa chua mới. Hàm pickle.dumps() đã hỗ trợ cờ văn bản hoặc nhị phân trong một thời gian dài. Trong 2.3, cờ này được xác định lại từ Boolean thành số nguyên: 0 là định dạng chọn chế độ văn bản cũ, 1 là định dạng nhị phân cũ và bây giờ 2 là định dạng mới dành riêng cho 2.3. Một hằng số mới, pickle.HIGHEST_PROTOCOL, có thể được sử dụng để chọn giao thức đẹp nhất hiện có.

Việc tháo dỡ không còn được coi là một hoạt động an toàn. pickle của 2.2 đã cung cấp các hook để cố gắng ngăn chặn việc bỏ chọn các lớp không an toàn (cụ thể là thuộc tính __safe_for_unpickling__), nhưng không có mã nào trong số này từng được kiểm tra và do đó tất cả đều bị loại bỏ trong 2.3. Bạn không nên bỏ chọn dữ liệu không đáng tin cậy trong bất kỳ phiên bản Python nào.

Để giảm chi phí tẩy chua cho các lớp kiểu mới, một giao diện mới để tùy chỉnh quá trình tẩy chua đã được thêm vào bằng ba phương pháp đặc biệt: __getstate__(), __setstate__()__getnewargs__(). Hãy tham khảo PEP 307 để biết ngữ nghĩa đầy đủ của các phương pháp này.

Là một cách để nén các phần mềm hơn nữa, giờ đây có thể sử dụng mã số nguyên thay vì các chuỗi dài để xác định các lớp được chọn. Quỹ phần mềm Python sẽ duy trì một danh sách các mã tiêu chuẩn hóa; cũng có nhiều loại mã để sử dụng riêng tư. Hiện tại không có mã nào được chỉ định.

Xem thêm

PEP 307 - Phần mở rộng cho giao thức dưa chua

Được viết và thực hiện bởi Guido van Rossum và Tim Peters.

Lát mở rộng

Kể từ Python 1.4, cú pháp cắt đã hỗ trợ đối số "bước" hoặc "sải bước" thứ ba tùy chọn. Ví dụ: đây đều là cú pháp Python hợp pháp: L[1:10:2], L[:-1:1], L[::-1]. Điều này đã được thêm vào Python theo yêu cầu của các nhà phát triển Python số, sử dụng rộng rãi đối số thứ ba. Tuy nhiên, các kiểu danh sách, bộ dữ liệu và chuỗi chuỗi tích hợp sẵn của Python chưa bao giờ hỗ trợ tính năng này, nên sẽ tăng TypeError nếu bạn dùng thử. Michael Hudson đã đóng góp một bản vá để khắc phục thiếu sót này.

Ví dụ: bây giờ bạn có thể dễ dàng trích xuất các thành phần của danh sách có chỉ mục chẵn

>>> L = phạm vi (10)
>>> L[::2]
[0, 2, 4, 6, 8]

Các giá trị âm cũng có tác dụng tạo một bản sao của cùng một danh sách theo thứ tự ngược lại:

>>> L[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Điều này cũng hoạt động với bộ dữ liệu, mảng và chuỗi

>>> s='abcd'
>>> s[::2]
'ac'
>>> s[::-1]
'dcba'

Nếu bạn có một chuỗi có thể thay đổi, chẳng hạn như một danh sách hoặc một mảng, bạn có thể gán hoặc xóa một lát cắt mở rộng, nhưng có một số khác biệt giữa việc gán cho các lát cắt mở rộng và thông thường. Việc gán cho một lát cắt thông thường có thể được sử dụng để thay đổi độ dài của chuỗi

>>> a = phạm vi (3)
>>> một
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> một
[0, 4, 5, 6]

Các lát cắt mở rộng không linh hoạt như vậy. Khi gán cho một lát cắt mở rộng, danh sách ở phía bên phải của câu lệnh phải chứa cùng số mục với lát cắt mà nó đang thay thế:

>>> a = phạm vi(4)
>>> một
[0, 1, 2, 3]
>>> một[::2]
[0, 2]
>>> a[::2] = [0, -1]
>>> một
[0, 1, -1, 3]
>>> a[::2] = [0,1,2]
Traceback (cuộc gọi gần đây nhất):
  Tệp "<stdin>", dòng 1, ở định dạng ?
ValueError: cố gắng gán chuỗi kích thước 3 cho lát mở rộng có kích thước 2

Việc xóa đơn giản hơn:

>>> a = phạm vi(4)
>>> một
[0, 1, 2, 3]
>>> một[::2]
[0, 2]
>>> del a[::2]
>>> một
[1, 3]

Giờ đây, người ta cũng có thể chuyển các đối tượng lát cắt sang các phương thức __getitem__() của các chuỗi tích hợp sẵn

>>> phạm vi(10).__getitem__(lát(0, 5, 2))
[0, 2, 4]

Hoặc sử dụng các đối tượng lát trực tiếp trong chỉ số dưới:

>>> phạm vi(10)[lát(0, 5, 2)]
[0, 2, 4]

Để đơn giản hóa việc triển khai các chuỗi hỗ trợ cắt mở rộng, các đối tượng lát cắt hiện có một phương thức indices(length), với độ dài của chuỗi, trả về một bộ dữ liệu (start, stop, step) có thể được chuyển trực tiếp tới range(). indices() xử lý các chỉ mục bị bỏ qua và nằm ngoài giới hạn theo cách nhất quán với các lát cắt thông thường (và cụm từ vô thưởng vô phạt này ẩn giấu một loạt các chi tiết khó hiểu!). Phương pháp này dự định sẽ được sử dụng như thế này

lớp FakeSeq:
    ...
    def calc_item(self, i):
        ...
    def __getitem__(bản thân, vật phẩm):
        nếu isinstance(item, slice):
            chỉ số = item.indices(len(self))
            return FakeSeq([self.calc_item(i) for i in range(*indices)])
        khác:
            trả về self.calc_item(i)

Từ ví dụ này, bạn cũng có thể thấy rằng đối tượng slice tích hợp hiện là đối tượng kiểu cho kiểu lát cắt và không còn là một hàm nữa. Điều này nhất quán với Python 2.2, trong đó int, str, v.v., cũng trải qua sự thay đổi tương tự.

Những thay đổi ngôn ngữ khác

Dưới đây là tất cả những thay đổi mà Python 2.3 thực hiện đối với ngôn ngữ Python cốt lõi.

  • Câu lệnh yield bây giờ luôn là một từ khóa, như được mô tả trong phần PEP 255: Máy phát điện đơn giản của tài liệu này.

  • Một chức năng tích hợp mới enumerate() đã được thêm vào, như được mô tả trong phần PEP 279: liệt kê() của tài liệu này.

  • Hai hằng số mới, TrueFalse đã được thêm vào cùng với loại bool tích hợp sẵn, như được mô tả trong phần PEP 285: Loại Boolean của tài liệu này.

  • Hàm tạo kiểu int() bây giờ sẽ trả về một số nguyên dài thay vì tăng OverflowError khi một chuỗi hoặc số dấu phẩy động quá lớn để vừa với một số nguyên. Điều này có thể dẫn đến một kết quả nghịch lý là isinstance(int(expression), int) là sai, nhưng điều đó dường như không gây ra vấn đề gì trong thực tế.

  • Các loại tích hợp hiện hỗ trợ cú pháp cắt mở rộng, như được mô tả trong phần Lát mở rộng của tài liệu này.

  • Một hàm tích hợp mới, sum(iterable, start=0), cộng các mục số trong đối tượng có thể lặp lại và trả về tổng của chúng. sum() chỉ chấp nhận số, nghĩa là bạn không thể sử dụng nó để nối một loạt chuỗi. (Được đóng góp bởi Alex Martelli.)

  • list.insert(pos, value) dùng để chèn value vào đầu danh sách khi pos âm. Hành vi hiện đã được thay đổi để nhất quán với việc lập chỉ mục lát cắt, vì vậy khi pos là -1, giá trị sẽ được chèn trước phần tử cuối cùng, v.v.

  • list.index(value), tìm kiếm value trong danh sách và trả về chỉ mục của nó, giờ đây lấy các đối số startstop tùy chọn để giới hạn tìm kiếm chỉ trong một phần của danh sách.

  • Từ điển có một phương thức mới, pop(key[, *default*]), trả về giá trị tương ứng với key và xóa cặp khóa/giá trị đó khỏi từ điển. Nếu khóa được yêu cầu không có trong từ điển, default sẽ được trả về nếu nó được chỉ định và KeyError sẽ được tăng lên nếu không có.

    >>> d = {1:2}
    >>> d
    {1: 2}
    >>> d.pop(4)
    Traceback (cuộc gọi gần đây nhất):
      Tệp "stdin", dòng 1, ở dạng ?
    Lỗi khóa: 4
    >>> d.pop(1)
    2
    >>> d.pop(1)
    Traceback (cuộc gọi gần đây nhất):
      Tệp "stdin", dòng 1, ở dạng ?
    KeyError: 'pop(): từ điển trống'
    >>> d
    {}
    >>>
    

    Ngoài ra còn có một phương thức lớp mới, dict.fromkeys(iterable, value), tạo ra một từ điển với các khóa được lấy từ iterator iterable được cung cấp và tất cả các giá trị được đặt thành value, mặc định là None.

    (Các bản vá do Raymond Hettinger đóng góp.)

    Ngoài ra, hàm tạo dict() hiện chấp nhận đối số từ khóa để đơn giản hóa việc tạo từ điển nhỏ

    >>> dict(đỏ=1, xanh dương=2, xanh lục=3, đen=4)
    {'xanh': 2, 'đen': 4, 'xanh': 3, 'đỏ': 1}
    

    (Được đóng góp bởi Just van Rossum.)

  • Câu lệnh assert không còn kiểm tra cờ __debug__ nữa, do đó bạn không thể tắt xác nhận bằng cách gán cho __debug__ nữa. Chạy Python bằng khóa chuyển -O vẫn sẽ tạo mã không thực thi bất kỳ xác nhận nào.

  • Hầu hết các đối tượng kiểu hiện đều có thể gọi được, vì vậy bạn có thể sử dụng chúng để tạo các đối tượng mới như hàm, lớp và mô-đun. (Điều này có nghĩa là mô-đun new có thể không được dùng nữa trong phiên bản Python trong tương lai, vì giờ đây bạn có thể sử dụng các đối tượng loại có sẵn trong mô-đun types.) Ví dụ: bạn có thể tạo một đối tượng mô-đun mới bằng mã sau:

    >>> nhập các loại
    >>> m = type.ModuleType('abc','docstring')
    >>> tôi
    <mô-đun 'abc' (tích hợp sẵn)>
    >>> m.__doc__
    'chuỗi tài liệu'
    
  • Một cảnh báo mới, PendingDeprecationWarning đã được thêm vào để biểu thị các tính năng sắp không được dùng nữa. Cảnh báo not sẽ được in theo mặc định. Để kiểm tra việc sử dụng các tính năng sẽ không được dùng nữa trong tương lai, hãy cung cấp -Walways::PendingDeprecationWarning:: trên dòng lệnh hoặc sử dụng warnings.filterwarnings().

  • Quá trình loại bỏ các ngoại lệ dựa trên chuỗi, như trong raise "Error occurred", đã bắt đầu. Việc nâng một chuỗi bây giờ sẽ kích hoạt PendingDeprecationWarning.

  • Bây giờ, việc sử dụng None làm tên biến sẽ dẫn đến cảnh báo SyntaxWarning. Trong phiên bản tương lai của Python, None cuối cùng có thể trở thành một từ khóa.

  • Phương thức xreadlines() của các đối tượng tệp, được giới thiệu trong Python 2.1, không còn cần thiết nữa vì các tệp hiện hoạt động như trình vòng lặp của chính chúng. xreadlines() ban đầu được giới thiệu là một cách nhanh hơn để lặp qua tất cả các dòng trong một tệp, nhưng giờ đây bạn có thể chỉ cần viết for line in file_obj. Các đối tượng tệp cũng có thuộc tính encoding chỉ đọc mới cung cấp mã hóa được tệp sử dụng; Các chuỗi Unicode được ghi vào tệp sẽ được tự động chuyển đổi thành byte bằng cách sử dụng mã hóa đã cho.

  • Thứ tự phân giải phương thức được sử dụng bởi các lớp kiểu mới đã thay đổi, mặc dù bạn sẽ chỉ nhận thấy sự khác biệt nếu bạn có hệ thống phân cấp kế thừa thực sự phức tạp. Các lớp cổ điển không bị ảnh hưởng bởi sự thay đổi này. Python 2.2 ban đầu sử dụng loại cấu trúc liên kết của tổ tiên của một lớp, nhưng 2.3 hiện sử dụng thuật toán C3 như được mô tả trong bài báo "A Monotonic Superclass Linearization for Dylan". Để hiểu động cơ của sự thay đổi này, hãy đọc bài viết Thứ tự phân giải phương thức Python 2.3 của Michele Simionato hoặc đọc chủ đề trên python-dev bắt đầu bằng thông báo tại https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni trước tiên đã chỉ ra vấn đề và cũng thực hiện sửa lỗi bằng cách mã hóa thuật toán C3.

  • Python chạy các chương trình đa luồng bằng cách chuyển đổi giữa các luồng sau khi thực thi N mã byte. Giá trị mặc định cho N đã được tăng từ 10 lên 100 mã byte, tăng tốc các ứng dụng đơn luồng bằng cách giảm chi phí chuyển đổi. Một số ứng dụng đa luồng có thể có thời gian phản hồi chậm hơn nhưng điều đó có thể dễ dàng khắc phục bằng cách đặt giới hạn về số thấp hơn bằng sys.setcheckinterval(N). Giới hạn có thể được truy xuất bằng chức năng sys.getcheckinterval() mới.

  • Một thay đổi nhỏ nhưng có ảnh hưởng sâu rộng là tên của các loại tiện ích mở rộng được xác định bởi các mô-đun đi kèm với Python hiện chứa mô-đun và '.' ở phía trước tên loại. Ví dụ: trong Python 2.2, nếu bạn đã tạo một ổ cắm và in __class__ của nó, bạn sẽ nhận được kết quả đầu ra này

    >>> s = socket.socket()
    >>> s.__class__
    <gõ 'ổ cắm'>
    

    Trong 2.3, bạn nhận được điều này:

    >>> s.__class__
    <gõ '_socket.socket'>
    
  • Một trong những điểm không tương thích được ghi nhận giữa các lớp kiểu cũ và kiểu mới đã bị loại bỏ: giờ đây bạn có thể gán cho các thuộc tính __name____bases__ của các lớp kiểu mới. Có một số hạn chế đối với những gì có thể được gán cho __bases__ cũng như những hạn chế liên quan đến việc gán cho thuộc tính __class__ của một phiên bản.

Thay đổi chuỗi

  • Toán tử in hiện hoạt động khác với chuỗi. Trước đây, khi đánh giá X in Y trong đó XY là các chuỗi, X chỉ có thể là một ký tự đơn. Điều đó bây giờ đã thay đổi; X có thể là một chuỗi có độ dài bất kỳ và X in Y sẽ trả về True nếu X là chuỗi con của Y. Nếu X là chuỗi trống thì kết quả luôn là True.

    >>> 'ab' trong 'abcd'
    đúng
    >>> 'quảng cáo' trong 'abcd'
    sai
    >>> '' trong 'abcd'
    đúng
    

    Lưu ý rằng điều này không cho bạn biết chuỗi con bắt đầu từ đâu; nếu bạn cần thông tin đó, hãy sử dụng phương thức chuỗi find().

  • Các phương thức chuỗi strip(), lstrip()rstrip() hiện có một đối số tùy chọn để chỉ định các ký tự cần loại bỏ. Mặc định vẫn là xóa hết các ký tự khoảng trắng:

    >>> ' abc '.strip()
    'abc'
    >>> '><><abc<><><>'.strip('<>')
    'abc'
    >>> '><><abc<><><>\n'.strip('<>')
    'abc<><><>\n'
    >>> u'\u4000\u4001abc\u4000'.strip(u'\u4000')
    u'\u4001abc'
    >>>
    

    (Được đề xuất bởi Simon Brunning và được thực hiện bởi Walter Dörwald.)

  • Các phương thức chuỗi startswith()endswith() hiện chấp nhận số âm cho tham số startend.

  • Một phương thức chuỗi mới khác là zfill(), ban đầu là một hàm trong mô-đun string. zfill() đệm một chuỗi số có các số 0 ở bên trái cho đến khi đạt chiều rộng được chỉ định. Lưu ý rằng toán tử % vẫn linh hoạt và mạnh mẽ hơn zfill().

    >>> '45'.zfill(4)
    '0045'
    >>> '12345'.zfill(4)
    '12345'
    >>> 'ngốc nghếch'.zfill(6)
    '0ngớ ngẩn'
    

    (Được đóng góp bởi Walter Dörwald.)

  • Một đối tượng kiểu mới, basestring, đã được thêm vào. Cả chuỗi 8 bit và chuỗi Unicode đều kế thừa từ loại này, vì vậy isinstance(obj, basestring) sẽ trả về True cho cả hai loại chuỗi. Đây là loại hoàn toàn trừu tượng, vì vậy bạn không thể tạo phiên bản basestring.

  • Các chuỗi nội bộ không còn bất tử và bây giờ sẽ được thu thập rác theo cách thông thường khi tham chiếu duy nhất đến chúng là từ từ điển nội bộ của các chuỗi nội bộ. (Được thực hiện bởi Oren Tirosh.)

Tối ưu hóa

  • Việc tạo các thể hiện của lớp kiểu mới đã được thực hiện nhanh hơn nhiều; giờ đây chúng nhanh hơn các lớp học cổ điển!

  • Phương thức sort() của các đối tượng danh sách đã được Tim Peters viết lại rộng rãi và việc triển khai nhanh hơn đáng kể.

  • Phép nhân các số nguyên lớn dài giờ đây nhanh hơn nhiều nhờ triển khai phép nhân Karatsuba, một thuật toán có tỷ lệ tốt hơn O(n2) cần thiết cho thuật toán nhân cấp phổ thông. (Bản vá gốc của Christopher A. Craig và được Tim Peters làm lại đáng kể.)

  • Opcode SET_LINENO hiện không còn nữa. Điều này có thể giúp tăng tốc độ một chút, tùy thuộc vào đặc điểm riêng của trình biên dịch của bạn. Xem phần Những thay đổi và sửa lỗi khác để được giải thích dài hơn. (Đã bị xóa bởi Michael Hudson.)

  • Các đối tượng xrange() hiện có trình vòng lặp riêng, làm cho for i in xrange(n) nhanh hơn một chút so với for i in range(n). (Bản vá của Raymond Hettinger.)

  • Một số sắp xếp lại nhỏ đã được thực hiện ở nhiều điểm phát sóng khác nhau để cải thiện hiệu suất, chẳng hạn như nội tuyến một hàm hoặc xóa một số mã. (Phần lớn được triển khai bởi GvR, nhưng rất nhiều người đã đóng góp những thay đổi riêng lẻ.)

Kết quả cuối cùng của việc tối ưu hóa 2.3 là Python 2.3 chạy điểm chuẩn pystone nhanh hơn khoảng 25% so với Python 2.2.

Các mô-đun mới, cải tiến và không được dùng nữa

Như thường lệ, thư viện chuẩn của Python nhận được một số cải tiến và sửa lỗi. Đây là danh sách một phần những thay đổi đáng chú ý nhất, được sắp xếp theo thứ tự bảng chữ cái theo tên mô-đun. Tham khảo tệp Misc/NEWS trong cây nguồn để biết danh sách thay đổi đầy đủ hơn hoặc xem qua nhật ký CVS để biết tất cả chi tiết.

  • Mô-đun array hiện hỗ trợ mảng ký tự Unicode sử dụng ký tự định dạng 'u'. Mảng hiện cũng hỗ trợ sử dụng toán tử gán += để thêm nội dung của mảng khác và toán tử gán *= để lặp lại một mảng. (Được đóng góp bởi Jason Orendorff.)

  • Mô-đun bsddb đã được thay thế bằng phiên bản 4.1.6 của gói PyBSDDB, cung cấp giao diện hoàn chỉnh hơn cho các tính năng giao dịch của thư viện BerkeleyDB.

    Phiên bản cũ của mô-đun đã được đổi tên thành bsddb185 và không còn được xây dựng tự động nữa; bạn sẽ phải chỉnh sửa Modules/Setup để kích hoạt nó. Lưu ý rằng gói bsddb mới được thiết kế để tương thích với mô-đun cũ, vì vậy hãy nhớ báo lỗi nếu bạn phát hiện bất kỳ sự không tương thích nào. Khi nâng cấp lên Python 2.3, nếu trình thông dịch mới được biên dịch bằng phiên bản mới của thư viện BerkeleyDB cơ bản, bạn gần như chắc chắn sẽ phải chuyển đổi các tệp cơ sở dữ liệu của mình sang phiên bản mới. Bạn có thể thực hiện việc này khá dễ dàng với các tập lệnh mới db2pickle.pypickle2db.py mà bạn sẽ tìm thấy trong thư mục Tools/scripts của bản phân phối. Nếu bạn đã sử dụng gói PyBSDDB và nhập dưới dạng bsddb3, bạn sẽ phải thay đổi câu lệnh import để nhập dưới dạng bsddb.

  • Mô-đun bz2 mới là giao diện cho thư viện nén dữ liệu bz2. Dữ liệu được nén bz2 thường nhỏ hơn dữ liệu được nén zlib- tương ứng. (Đóng góp bởi Gustavo Niemeyer.)

  • Một tập hợp các loại ngày/giờ tiêu chuẩn đã được thêm vào mô-đun datetime mới. Xem phần sau để biết thêm chi tiết.

  • Lớp Distutils Extension hiện hỗ trợ một đối số hàm tạo bổ sung có tên depends để liệt kê các tệp nguồn bổ sung mà tiện ích mở rộng phụ thuộc vào. Điều này cho phép Distutils biên dịch lại mô-đun nếu bất kỳ tệp phụ thuộc nào bị sửa đổi. Ví dụ: nếu sampmodule.c bao gồm tệp tiêu đề sample.h, bạn sẽ tạo đối tượng Extension như thế này:

    ext = Tiện ích mở rộng ("samp",
                    nguồn=["sampmodule.c"],
                    phụ thuộc=["sample.h"])
    

    Việc sửa đổi sample.h sau đó sẽ khiến mô-đun được biên dịch lại. (Được đóng góp bởi Jeremy Hylton.)

  • Những thay đổi nhỏ khác đối với Distutils: hiện tại nó kiểm tra các biến môi trường CC, CFLAGS, CPP, LDFLAGSCPPFLAGS, sử dụng chúng để ghi đè cài đặt trong cấu hình của Python (do Robert Weber đóng góp).

  • Trước đây, mô-đun doctest sẽ chỉ tìm kiếm các chuỗi tài liệu của các phương thức và hàm công khai cho các trường hợp thử nghiệm, nhưng giờ đây nó cũng kiểm tra các chuỗi riêng tư. Hàm DocTestSuite() tạo đối tượng unittest.TestSuite từ một tập hợp các bài kiểm tra doctest.

  • Hàm gc.get_referents(object) mới trả về danh sách tất cả các đối tượng được tham chiếu bởi object.

  • Mô-đun getopt có được một chức năng mới, gnu_getopt(), hỗ trợ các đối số tương tự như chức năng getopt() hiện có nhưng sử dụng chế độ quét kiểu GNU. getopt() hiện tại dừng xử lý các tùy chọn ngay khi gặp phải đối số không phải tùy chọn, nhưng ở chế độ kiểu GNU, quá trình xử lý vẫn tiếp tục, nghĩa là các tùy chọn và đối số có thể được trộn lẫn. Ví dụ:

    >>> getopt.getopt(['-f', 'tên tệp', 'đầu ra', '-v'], 'f:v')
    ([('-f', 'tên tệp')], ['đầu ra', '-v'])
    >>> getopt.gnu_getopt(['-f', 'tên tệp', 'đầu ra', '-v'], 'f:v')
    ([('-f', 'tên tệp'), ('-v', '')], ['đầu ra'])
    

    (Được đóng góp bởi Peter Åstrand.)

  • Các mô-đun grp, pwdresource hiện trả về các bộ dữ liệu nâng cao:

    >>> nhập khẩu grp
    >>> g = grp.getgrnam('amk')
    >>> g.gr_name, g.gr_gid
    ('amk', 500)
    
  • Mô-đun gzip hiện có thể xử lý các tệp vượt quá 2 GiB.

  • Mô-đun heapq mới chứa phần triển khai thuật toán xếp hàng đống. Đống là một cấu trúc dữ liệu giống như mảng giúp giữ các mục theo thứ tự được sắp xếp một phần sao cho đối với mọi chỉ mục k, heap[k] <= heap[2*k+1]heap[k] <= heap[2*k+2]. Điều này giúp nhanh chóng loại bỏ mục nhỏ nhất và chèn mục mới trong khi vẫn duy trì thuộc tính heap là O(log n). (Xem https://xlinux.nist.gov/dads//HTML/priorityque.html để biết thêm thông tin về cấu trúc dữ liệu hàng đợi ưu tiên.)

    Mô-đun heapq cung cấp các hàm heappush()heappop() để thêm và xóa các mục trong khi vẫn duy trì thuộc tính heap trên một số loại chuỗi Python có thể thay đổi khác. Đây là một ví dụ sử dụng danh sách Python:

    >>> nhập heapq
    >>> đống = []
    >>> cho mục trong [3, 7, 5, 11, 1]:
    ... heapq.heappush(đống, mục)
    ...
    >>> đống
    [1, 3, 5, 11, 7]
    >>> heapq.heappop(đống)
    1
    >>> heapq.heappop(đống)
    3
    >>> đống
    [5, 7, 11]
    

    (Được đóng góp bởi Kevin O'Connor.)

  • Môi trường phát triển tích hợp IDLE đã được cập nhật bằng mã từ dự án IDLEfork (https://idlefork.sourceforge.net). Tính năng đáng chú ý nhất là mã đang được phát triển hiện được thực thi trong một quy trình con, nghĩa là không còn cần các thao tác reload() thủ công nữa. Mã lõi của IDLE đã được tích hợp vào thư viện tiêu chuẩn dưới dạng gói idlelib.

  • Mô-đun imaplib hiện hỗ trợ IMAP trên SSL. (Được đóng góp bởi Piers Lauder và Tino Lange.)

  • Zz000zz chứa một số hàm hữu ích để sử dụng với các trình vòng lặp, lấy cảm hứng từ các hàm khác nhau do ngôn ngữ ML và Haskell cung cấp. Ví dụ: itertools.ifilter(predicate, iterator) trả về tất cả các phần tử trong trình vòng lặp mà hàm predicate() trả về Trueitertools.repeat(obj, N) trả về obj N lần. Có một số chức năng khác trong mô-đun; xem tài liệu tham khảo của gói để biết chi tiết. (Được đóng góp bởi Raymond Hettinger.)

  • Hai chức năng mới trong mô-đun math, degrees(rads)radians(degs), chuyển đổi giữa radian và độ. Các hàm khác trong mô-đun math như math.sin()math.cos() luôn yêu cầu các giá trị đầu vào được đo bằng radian. Ngoài ra, một đối số base tùy chọn đã được thêm vào math.log() để giúp tính toán logarit cho các cơ số khác ngoài e10 dễ dàng hơn. (Được đóng góp bởi Raymond Hettinger.)

  • Một số chức năng POSIX mới (getpgid(), killpg(), lchown(), loadavg(), major(), makedev(), minor()mknod()) đã được thêm vào mô-đun posix làm nền tảng cho mô-đun os. (Được đóng góp bởi Gustavo Niemeyer, Geert Jansen và Denis S. Otkidach.)

  • Trong mô-đun os, nhóm hàm *stat() hiện có thể báo cáo các phân số của giây trong dấu thời gian. Các dấu thời gian như vậy được biểu diễn dưới dạng số float, tương tự như giá trị được trả về bởi time.time().

    Trong quá trình thử nghiệm, người ta nhận thấy rằng một số ứng dụng sẽ bị hỏng nếu dấu thời gian ở dạng nổi. Để tương thích, khi sử dụng giao diện tuple của tem thời gian stat_result sẽ được biểu diễn dưới dạng số nguyên. Khi sử dụng các trường được đặt tên (một tính năng được giới thiệu lần đầu trong Python 2.2), dấu thời gian vẫn được biểu thị dưới dạng số nguyên, trừ khi os.stat_float_times() được gọi để bật giá trị trả về float

    >>> os.stat("/tmp").st_mtime
    1034791200
    >>> os.stat_float_times(Đúng)
    >>> os.stat("/tmp").st_mtime
    1034791200.6335014
    

    Trong Python 2.4, mặc định sẽ thay đổi thành luôn trả về số float.

    Các nhà phát triển ứng dụng chỉ nên bật tính năng này nếu tất cả thư viện của họ hoạt động bình thường khi gặp dấu thời gian dấu phẩy động hoặc nếu họ sử dụng bộ dữ liệu API. Nếu được sử dụng, tính năng này phải được kích hoạt ở cấp độ ứng dụng thay vì cố gắng kích hoạt nó theo từng lần sử dụng.

  • Mô-đun optparse chứa một trình phân tích cú pháp mới cho các đối số dòng lệnh có thể chuyển đổi các giá trị tùy chọn thành một loại Python cụ thể và sẽ tự động tạo thông báo sử dụng. Xem phần sau để biết thêm chi tiết.

  • Mô-đun linuxaudiodev cũ và chưa từng được ghi lại đã không được dùng nữa và một phiên bản mới có tên ossaudiodev đã được thêm vào. Mô-đun này được đổi tên vì trình điều khiển âm thanh OSS có thể được sử dụng trên các nền tảng khác ngoài Linux và giao diện cũng đã được dọn dẹp và cập nhật theo nhiều cách khác nhau. (Được đóng góp bởi Greg Ward và Nicholas FitzRoy-Dale.)

  • Mô-đun platform mới chứa một số chức năng cố gắng xác định các thuộc tính khác nhau của nền tảng bạn đang chạy. Có các chức năng để lấy kiến ​​trúc, loại CPU, phiên bản hệ điều hành Windows và thậm chí cả phiên bản phân phối Linux. (Được đóng góp bởi Marc-André Lemburg.)

  • Các đối tượng trình phân tích cú pháp do mô-đun pyexpat cung cấp hiện có thể tùy chọn đệm dữ liệu ký tự, dẫn đến ít lệnh gọi đến trình xử lý dữ liệu ký tự của bạn hơn và do đó hiệu suất nhanh hơn. Đặt thuộc tính buffer_text của đối tượng phân tích cú pháp thành True sẽ cho phép lưu vào bộ đệm.

  • Chức năng sample(population, k) đã được thêm vào mô-đun random. population là một chuỗi hoặc đối tượng xrange chứa các phần tử của một tập hợp và sample() chọn các phần tử k từ tập hợp mà không thay thế các phần tử đã chọn. k có thể có bất kỳ giá trị nào lên tới len(population). Ví dụ:

    >>> ngày = ['Mo', 'Tu', 'Chúng tôi', 'Th', 'Fr', 'St', 'Sn']
    >>> ngẫu nhiên.sample(ngày, 3) # Choose 3 phần tử
    ['St', 'Sn', 'Th']
    >>> ngẫu nhiên.sample(ngày, 7) # Choose 7 phần tử
    ['Tu', 'Th', 'Mo', 'Chúng tôi', 'St', 'Fr', 'Sn']
    >>> ngẫu nhiên.sample(ngày, 7) # Choose 7 nữa
    ['Chúng tôi', 'Mo', 'Sn', 'Fr', 'Tu', 'St', 'Th']
    >>> ngẫu nhiên.sample(ngày, 8) # Can không chọn tám
    Traceback (cuộc gọi gần đây nhất):
      Tệp "<stdin>", dòng 1, ở định dạng ?
      Tệp "random.py", dòng 414, trong mẫu
          raise ValueError, "mẫu lớn hơn dân số"
    ValueError: mẫu lớn hơn dân số
    >>> ngẫu nhiên.sample(xrange(1,10000,2), 10) # Choose mười số lẻ. dưới 10000
    [3407, 3805, 1505, 7023, 2401, 2267, 9733, 3151, 8083, 9195]
    

    Mô-đun random hiện sử dụng thuật toán mới, Mersenne Twister, được triển khai trong C. Thuật toán này nhanh hơn và được nghiên cứu rộng rãi hơn thuật toán trước đó.

    (Tất cả những thay đổi được đóng góp bởi Raymond Hettinger.)

  • Mô-đun readline cũng có một số chức năng mới: get_history_item(), get_current_history_length()redisplay().

  • Các mô-đun rexecBastion đã được tuyên bố là đã chết và các nỗ lực nhập chúng sẽ không thành công với RuntimeError. Các lớp kiểu mới cung cấp những cách mới để thoát ra khỏi môi trường thực thi bị hạn chế do rexec cung cấp và không ai quan tâm đến việc sửa chúng hoặc có thời gian để làm việc đó. Nếu bạn có các ứng dụng sử dụng rexec, hãy viết lại chúng để sử dụng thứ khác.

    (Việc sử dụng Python 2.2 hoặc 2.1 sẽ không làm cho ứng dụng của bạn an toàn hơn chút nào vì có những lỗi đã biết trong mô-đun rexec trong các phiên bản đó. Xin nhắc lại: nếu bạn đang sử dụng rexec, hãy ngừng sử dụng nó ngay lập tức.)

  • Mô-đun rotor không được dùng nữa vì thuật toán mà nó sử dụng để mã hóa được cho là không an toàn. Nếu bạn cần mã hóa, hãy sử dụng một trong số các mô-đun Python AES có sẵn riêng.

  • Mô-đun shutil có chức năng move(src, dest) để di chuyển đệ quy một tệp hoặc thư mục đến một vị trí mới.

  • Hỗ trợ xử lý tín hiệu POSIX nâng cao hơn đã được thêm vào signal nhưng sau đó lại bị xóa vì chứng minh là không thể làm cho nó hoạt động đáng tin cậy trên các nền tảng.

  • Mô-đun socket hiện hỗ trợ thời gian chờ. Bạn có thể gọi phương thức settimeout(t) trên đối tượng socket để đặt thời gian chờ là t giây. Các thao tác ổ cắm tiếp theo mất nhiều hơn t giây để hoàn thành sẽ hủy bỏ và đưa ra ngoại lệ socket.timeout.

    Việc triển khai thời gian chờ ban đầu là của Tim O'Malley. Michael Gilfix đã tích hợp nó vào mô-đun socket của Python và hướng dẫn nó qua một bài đánh giá dài. Sau khi mã được kiểm tra, Guido van Rossum đã viết lại các phần của nó. (Đây là một ví dụ điển hình về quá trình phát triển hợp tác đang hoạt động.)

  • Trên Windows, mô-đun socket hiện có hỗ trợ Lớp cổng bảo mật (SSL).

  • Giá trị của macro C PYTHON_API_VERSION hiện được hiển thị ở cấp độ Python dưới dạng sys.api_version. Ngoại lệ hiện tại có thể được xóa bằng cách gọi hàm sys.exc_clear() mới.

  • Mô-đun tarfile mới cho phép đọc và ghi vào các tệp lưu trữ định dạng tar-. (Được đóng góp bởi Lars Gustäbel.)

  • Mô-đun textwrap mới chứa các chức năng gói các chuỗi chứa các đoạn văn bản. Hàm wrap(text, width) lấy một chuỗi và trả về một danh sách chứa văn bản được chia thành các dòng có chiều rộng không quá độ rộng đã chọn. Hàm fill(text, width) trả về một chuỗi đơn, được định dạng lại để vừa với các dòng không dài hơn chiều rộng đã chọn. (Như bạn có thể đoán, fill() được xây dựng dựa trên wrap(). Ví dụ:

    >>> nhập gói văn bản
    >>> đoạn = "Không một chút nào, chúng tôi bất chấp điềm báo: ... thêm văn bản ..."
    >>> textwrap.wrap(đoạn, 60)
    ["Không hề, chúng tôi bất chấp điềm báo: có một sự quan phòng đặc biệt trong",
     "sự rơi của một con chim sẻ. Nếu nó xảy ra bây giờ, nó sẽ không đến; nếu nó",
     ...]
    >>> print textwrap.fill(đoạn, 35)
    Không một chút nào, chúng tôi bất chấp điềm báo: có
    một sự quan phòng đặc biệt vào mùa thu
    một con chim sẻ. Nếu là bây giờ thì không
    đến ; nếu nó không đến thì nó
    sẽ là bây giờ; nếu không phải bây giờ
    nó sẽ tới: sự sẵn sàng là tất cả.
    >>>
    

    Mô-đun này cũng chứa lớp TextWrapper thực sự triển khai chiến lược gói văn bản. Cả lớp TextWrapper và các hàm wrap()fill() đều hỗ trợ một số đối số từ khóa bổ sung để tinh chỉnh định dạng; tham khảo tài liệu của mô-đun để biết chi tiết. (Được đóng góp bởi Greg Ward.)

  • Các mô-đun threadthreading hiện có các mô-đun đồng hành, dummy_threaddummy_threading, cung cấp khả năng triển khai không cần làm gì đối với giao diện của mô-đun thread cho các nền tảng không hỗ trợ các luồng. Mục đích là để đơn giản hóa các mô-đun nhận biết luồng (những mô-đun mà don't dựa vào các luồng để chạy) bằng cách đặt đoạn mã sau lên trên cùng:

    thử:
        nhập luồng dưới dạng _threading
    ngoại trừ lỗi nhập khẩu:
        nhập dummy_threading dưới dạng _threading
    

    Trong ví dụ này, _threading được sử dụng làm tên mô-đun để làm rõ rằng mô-đun đang được sử dụng không nhất thiết phải là mô-đun threading thực tế. Mã có thể gọi các hàm và sử dụng các lớp trong _threading cho dù các luồng có được hỗ trợ hay không, tránh câu lệnh if và làm cho mã rõ ràng hơn một chút. Mô-đun này sẽ không làm cho mã đa luồng chạy mà không có luồng một cách kỳ diệu; mã chờ một luồng khác quay lại hoặc thực hiện điều gì đó sẽ bị treo vĩnh viễn.

  • Chức năng strptime() của mô-đun time từ lâu đã gây khó chịu vì nó sử dụng triển khai strptime() của thư viện nền tảng C và các nền tảng khác nhau đôi khi có các lỗi kỳ lạ. Brett Cannon đã đóng góp một triển khai di động được viết bằng Python thuần túy và sẽ hoạt động giống hệt nhau trên tất cả các nền tảng.

  • Mô-đun timeit mới giúp đo thời gian thực thi các đoạn mã Python. Tệp timeit.py có thể được chạy trực tiếp từ dòng lệnh hoặc lớp Timer của mô-đun có thể được nhập và sử dụng trực tiếp. Sau đây là một ví dụ ngắn để tìm hiểu xem việc chuyển đổi chuỗi 8 bit thành Unicode có nhanh hơn hay không bằng cách thêm một chuỗi Unicode trống vào chuỗi đó hay bằng cách sử dụng hàm unicode():

    thời gian nhập khẩu
    
    hẹn giờ1 = timeit.Timer('unicode("abc")')
    time2 = timeit.Timer('"abc" + u""')
    
    # Run ba thử nghiệm
    in bộ đếm thời gian1.repeat(lặp lại=3, số=100000)
    in bộ đếm thời gian2.repeat(lặp lại=3, số=100000)
    
    # On máy tính xách tay của tôi xuất ra kết quả này:
    # [0,36831796169281006, 0,37441694736480713, 0,35304892063140869]
    # [0,17574405670166016, 0,18193507194519043, 0,17565798759460449]
    
  • Mô-đun Tix đã nhận được nhiều bản sửa lỗi và cập nhật khác nhau cho phiên bản hiện tại của gói Tix.

  • Mô-đun Tkinter hiện hoạt động với phiên bản Tcl hỗ trợ luồng. Mô hình phân luồng của Tcl yêu cầu các tiện ích chỉ được truy cập từ luồng mà chúng được tạo; truy cập từ một luồng khác có thể khiến Tcl hoảng sợ. Đối với một số giao diện Tcl nhất định, Tkinter giờ đây sẽ tự động tránh điều này khi một tiện ích được truy cập từ một luồng khác bằng cách sắp xếp một lệnh, chuyển nó đến đúng luồng và chờ kết quả. Các giao diện khác không thể được xử lý tự động nhưng Tkinter giờ đây sẽ đưa ra một ngoại lệ đối với quyền truy cập như vậy để ít nhất bạn có thể tìm hiểu về sự cố. Xem https://mail.python.org/pipermail/python-dev/2002-December/031107.html để được giải thích chi tiết hơn về sự thay đổi này. (Được thực hiện bởi Martin von Löwis.)

  • Gọi các phương thức Tcl thông qua _tkinter không còn chỉ trả về chuỗi nữa. Thay vào đó, nếu Tcl trả về các đối tượng khác thì các đối tượng đó sẽ được chuyển đổi thành đối tượng Python tương đương của chúng, nếu có tồn tại hoặc được bao bọc bằng đối tượng _tkinter.Tcl_Obj nếu không tồn tại đối tượng Python tương đương. Hành vi này có thể được kiểm soát thông qua phương thức wantobjects() của đối tượng tkapp.

    Khi sử dụng _tkinter thông qua mô-đun Tkinter (như hầu hết các ứng dụng Tkinter), tính năng này luôn được kích hoạt. Nó không gây ra vấn đề tương thích vì Tkinter sẽ luôn chuyển đổi kết quả chuỗi thành kiểu Python nếu có thể.

    Nếu tìm thấy bất kỳ sự không tương thích nào, hành vi cũ có thể được khôi phục bằng cách đặt biến wantobjects trong mô-đun Tkinter thành false trước khi tạo đối tượng tkapp đầu tiên.

    nhập khẩu Tkinter
    Tkinter.wantobjects = 0
    

    Bất kỳ hư hỏng nào do thay đổi này gây ra sẽ được báo cáo là lỗi.

  • Mô-đun UserDict có lớp DictMixin mới xác định tất cả các phương thức từ điển cho các lớp đã có giao diện ánh xạ tối thiểu. Điều này giúp đơn giản hóa rất nhiều việc viết các lớp cần thay thế cho từ điển, chẳng hạn như các lớp trong mô-đun shelve.

    Việc thêm phần kết hợp dưới dạng siêu lớp sẽ cung cấp giao diện từ điển đầy đủ bất cứ khi nào lớp đó định nghĩa __getitem__(), __setitem__(), __delitem__()keys(). Ví dụ:

    >>> nhập UserDict
    >>> lớp SeqDict(UserDict.DictMixin):
    ... """Trông giống từ điển được triển khai bằng danh sách."""
    ... def __init__(self):
    ... self.keylist = []
    ... self.valuelist = []
    ... def __getitem__(self, key):
    ... thử:
    ... i = self.keylist.index(key)
    ... ngoại trừ ValueError:
    ... nâng KeyError
    ... trả về self.valuelist[i]
    ... def __setitem__(self, key, value):
    ... thử:
    ... i = self.keylist.index(key)
    ... self.valuelist[i] = giá trị
    ... ngoại trừ ValueError:
    ... self.keylist.append(key)
    ... self.valuelist.append(giá trị)
    ... def __delitem__(self, key):
    ... thử:
    ... i = self.keylist.index(key)
    ... ngoại trừ ValueError:
    ... nâng KeyError
    ... self.keylist.pop(i)
    ... self.valuelist.pop(i)
    ... phím def (tự):
    ... danh sách trả về(self.keylist)
    ...
    >>> s = SeqDict()
    >>> dir(s) # See rằng các phương pháp từ điển khác được triển khai
    ['__cmp__', '__contains__', '__delitem__', '__doc__', '__getitem__',
     '__init__', '__iter__', '__len__', '__module__', '__repr__',
     '__setitem__', 'xóa', 'lấy', 'has_key', 'items', 'iteritems',
     'iterkeys', 'itervalues', 'keylist', 'keys', 'pop', 'popitem',
     'setdefault', 'cập nhật', 'danh sách giá trị', 'giá trị']
    

    (Được đóng góp bởi Raymond Hettinger.)

  • Việc triển khai DOM trong xml.dom.minidom hiện có thể tạo đầu ra XML ở một mã hóa cụ thể bằng cách cung cấp đối số mã hóa tùy chọn cho các phương thức toxml()toprettyxml() của các nút DOM.

  • Mô-đun xmlrpclib hiện hỗ trợ tiện ích mở rộng XML-RPC để xử lý các giá trị dữ liệu bằng 0, chẳng hạn như None của Python. Các giá trị nil luôn được hỗ trợ khi sắp xếp lại phản hồi XML-RPC. Để tạo các yêu cầu chứa None, bạn phải cung cấp giá trị thực cho tham số allow_none khi tạo phiên bản Marshaller.

  • Mô-đun DocXMLRPCServer mới cho phép ghi các máy chủ XML-RPC tự ghi tài liệu. Chạy nó ở chế độ demo (dưới dạng chương trình) để xem nó hoạt động. Việc trỏ trình duyệt web tới máy chủ RPC sẽ tạo ra tài liệu kiểu pydoc; trỏ xmlrpclib tới máy chủ cho phép gọi các phương thức thực tế. (Được đóng góp bởi Brian Quinlan.)

  • Hỗ trợ cho các tên miền quốc tế hóa (RFC 3454, 3490, 3491 và 3492) đã được thêm vào. Mã hóa "idna" có thể được sử dụng để chuyển đổi giữa tên miền Unicode và mã hóa tương thích ASCII (ACE) của tên đó.

    >{}>{}> u"www.Alliancefrançaise.nu".encode("idna")
    'www.xn--alliancefranaise-npb.nu'
    

    Mô-đun socket cũng đã được mở rộng để chuyển đổi một cách minh bạch tên máy chủ Unicode sang phiên bản ACE trước khi chuyển chúng sang thư viện C. Các mô-đun xử lý tên máy chủ như httplibftplib) cũng hỗ trợ tên máy chủ Unicode; httplib cũng gửi tiêu đề HTTP Host bằng phiên bản ACE của tên miền. urllib hỗ trợ các URL Unicode có tên máy chủ không phải là ASCII miễn là phần path của URL chỉ là ASCII.

    Để thực hiện thay đổi này, mô-đun stringprep, công cụ mkstringprep và mã hóa punycode đã được thêm vào.

Loại ngày/giờ

Các loại ngày và giờ phù hợp để thể hiện dấu thời gian đã được thêm dưới dạng mô-đun datetime. Các loại này không hỗ trợ các lịch khác nhau hoặc nhiều tính năng ưa thích và chỉ tuân theo các khái niệm cơ bản về biểu thị thời gian.

Ba loại chính là: date, đại diện cho ngày, tháng và năm; time, bao gồm giờ, phút và giây; và datetime, chứa tất cả các thuộc tính của cả datetime. Ngoài ra còn có một lớp timedelta biểu thị sự khác biệt giữa hai thời điểm và logic múi giờ được triển khai bởi các lớp kế thừa từ lớp tzinfo trừu tượng.

Bạn có thể tạo các phiên bản của datetime bằng cách cung cấp đối số từ khóa cho hàm tạo thích hợp, ví dụ: datetime.date(year=1972, month=10, day=15) hoặc bằng cách sử dụng một trong số các phương thức lớp. Ví dụ: phương thức lớp today() trả về ngày cục bộ hiện tại.

Sau khi được tạo, các phiên bản của lớp ngày/giờ đều không thể thay đổi. Có một số phương pháp để tạo chuỗi được định dạng từ các đối tượng:

>>> nhập ngày giờ dưới dạng dt
>>> bây giờ = dt.datetime.now()
>>> ngay bây giờ.isoformat()
'2002-12-30T21:27:03.994956'
>>> now.ctime() # Only có sẵn theo ngày, giờ
'Thứ Hai ngày 30 tháng 12 21:27:03 2002'
>>> now.strftime('%Y %d %b')
'2002 30 tháng 12'

Phương thức replace() cho phép sửa đổi một hoặc nhiều trường của phiên bản date hoặc datetime, trả về một phiên bản mới

>>> d = dt.datetime.now()
>>> d
datetime.datetime(2002, 12, 30, 22, 15, 38, 827738)
>>> d.replace(năm=2001, giờ=12)
datetime.datetime(2001, 12, 30, 12, 15, 38, 827738)
>>>

Các phiên bản có thể được so sánh, băm và chuyển đổi thành chuỗi (kết quả giống như kết quả của isoformat()). Các phiên bản datedatetime có thể được trừ lẫn nhau và thêm vào các phiên bản timedelta. Tính năng còn thiếu lớn nhất là không có thư viện tiêu chuẩn hỗ trợ phân tích chuỗi và lấy lại date hoặc datetime.

Để biết thêm thông tin, hãy tham khảo tài liệu tham khảo của mô-đun. (Được đóng góp bởi Tim Peters.)

Mô-đun optparse

Mô-đun getopt cung cấp khả năng phân tích cú pháp đơn giản các đối số dòng lệnh. Mô-đun optparse mới (tên ban đầu là Optik) cung cấp khả năng phân tích dòng lệnh phức tạp hơn tuân theo các quy ước Unix, tự động tạo đầu ra cho --help và có thể thực hiện các hành động khác nhau cho các tùy chọn khác nhau.

Bạn bắt đầu bằng cách tạo một phiên bản của OptionParser và cho nó biết các tùy chọn của chương trình của bạn.

hệ thống nhập khẩu
từ nhập optparse OptionParser

op = OptionParser()
op.add_option('-i', '--input',
              action='store', type='string', dest='input',
              help='đặt tên file đầu vào')
op.add_option('-l', '--length',
              action='store', type='int', dest='length',
              help='đặt độ dài đầu ra tối đa')

Việc phân tích dòng lệnh sau đó được thực hiện bằng cách gọi phương thức parse_args().

tùy chọn, args = op.parse_args(sys.argv[1:])
tùy chọn in
in lập luận

Điều này trả về một đối tượng chứa tất cả các giá trị tùy chọn và danh sách các chuỗi chứa các đối số còn lại.

Việc gọi tập lệnh với nhiều đối số khác nhau hiện hoạt động như bạn mong đợi. Lưu ý rằng đối số độ dài được tự động chuyển đổi thành số nguyên.

$ ./python opt.py -i data arg1
<Giá trị tại 0x400cad4c: {'input': 'data', 'length': None}>
['arg1']
$ ./python opt.py --input=data --length=4
<Các giá trị ở 0x400cad2c: {'input': 'data', 'length': 4}>
[]
$

Thông báo trợ giúp được tạo tự động cho bạn:

$ ./python opt.py --help
cách sử dụng: opt.py [tùy chọn]

tùy chọn:
  -h, --help hiển thị thông báo trợ giúp này và thoát
  -iINPUT, --input=INPUT
                        đặt tên tệp đầu vào
  -lLENGTH, --length=LENGTH
                        đặt độ dài đầu ra tối đa
$

Xem tài liệu của mô-đun để biết thêm chi tiết.

Optik được viết bởi Greg Ward, với sự gợi ý từ độc giả của Getopt SIG.

Pymalloc: Công cụ phân bổ đối tượng chuyên dụng

Pymalloc, một công cụ cấp phát đối tượng chuyên dụng được viết bởi Vladimir Marangozov, là một tính năng được thêm vào Python 2.1. Pymalloc được thiết kế để nhanh hơn hệ thống malloc() và có ít chi phí bộ nhớ hơn cho các mẫu phân bổ điển hình của chương trình Python. Bộ cấp phát sử dụng hàm malloc() của C để có được vùng bộ nhớ lớn, sau đó đáp ứng các yêu cầu bộ nhớ nhỏ hơn từ các vùng này.

Trong 2.1 và 2.2, pymalloc là một tính năng thử nghiệm và không được bật theo mặc định; bạn phải kích hoạt nó một cách rõ ràng khi biên dịch Python bằng cách cung cấp tùy chọn --with-pymalloc cho tập lệnh configure. Trong phiên bản 2.3, pymalloc đã có nhiều cải tiến hơn và hiện được bật theo mặc định; bạn sẽ phải cung cấp --without-pymalloc để vô hiệu hóa nó.

Thay đổi này là minh bạch đối với mã được viết bằng Python; tuy nhiên, pymalloc có thể phát hiện lỗi trong phần mở rộng C. Tác giả của mô-đun mở rộng C nên kiểm tra mã của họ khi bật pymalloc, vì một số mã không chính xác có thể gây ra hiện tượng kết xuất lõi khi chạy.

Có một lỗi đặc biệt phổ biến gây ra vấn đề. Có một số hàm cấp phát bộ nhớ trong C API của Python trước đây chỉ là bí danh cho malloc()free() của thư viện C, nghĩa là nếu bạn vô tình gọi các hàm không khớp thì lỗi sẽ không đáng chú ý. Khi bật bộ cấp phát đối tượng, các hàm này không còn là bí danh của malloc()free() nữa và việc gọi sai hàm để giải phóng bộ nhớ có thể khiến bạn bị kết xuất lõi. Ví dụ: nếu bộ nhớ được cấp phát bằng PyObject_Malloc() thì nó phải được giải phóng bằng PyObject_Free() chứ không phải free(). Một số mô-đun đi kèm với Python đã gặp phải lỗi này và phải sửa; chắc chắn sẽ có nhiều mô-đun bên thứ ba gặp vấn đề tương tự.

Là một phần của thay đổi này, nhiều giao diện khó hiểu để phân bổ bộ nhớ đã được hợp nhất thành hai họ API. Bộ nhớ được phân bổ cho một họ không được bị thao túng bởi các chức năng từ họ kia. Có một họ để phân bổ các khối bộ nhớ và một nhóm hàm khác dành riêng cho việc phân bổ các đối tượng Python.

Nhờ có rất nhiều công việc của Tim Peters, pymalloc trong 2.3 cũng cung cấp các tính năng gỡ lỗi để ghi đè bộ nhớ và giải phóng gấp đôi trong cả mô-đun mở rộng và trong chính trình thông dịch. Để kích hoạt hỗ trợ này, hãy biên dịch phiên bản gỡ lỗi của trình thông dịch Python bằng cách chạy configure với --with-pydebug.

Để hỗ trợ người viết tiện ích mở rộng, tệp tiêu đề Misc/pymemcompat.h được phân phối cùng với nguồn tới Python 2.3, cho phép tiện ích mở rộng Python sử dụng giao diện 2.3 để phân bổ bộ nhớ trong khi biên dịch theo bất kỳ phiên bản Python nào kể từ 1.5.2. Bạn sẽ sao chép tệp từ bản phân phối nguồn của Python và gói nó cùng với nguồn tiện ích mở rộng của bạn.

Xem thêm

https://hg.python.org/cpython/file/default/Objects/obmalloc.c

Để biết chi tiết đầy đủ về cách triển khai pymalloc, hãy xem nhận xét ở đầu tệp Objects/obmalloc.c trong mã nguồn Python. Liên kết trên trỏ đến tệp trong trình duyệt python.org SVN.

Xây dựng và thay đổi C API

Những thay đổi trong quá trình xây dựng của Python và C API bao gồm:

  • Việc triển khai phát hiện chu trình được sử dụng bởi bộ thu gom rác đã được chứng minh là ổn định, vì vậy hiện tại nó đã được thực hiện bắt buộc. Bạn không thể biên dịch Python mà không có nó nữa và việc chuyển --with-cycle-gc sang configure đã bị xóa.

  • Giờ đây, Python có thể được xây dựng tùy ý dưới dạng thư viện dùng chung (libpython2.3.so) bằng cách cung cấp --enable-shared khi chạy tập lệnh configure của Python. (Được đóng góp bởi Ondrej Palkovsky.)

  • Các macro DL_EXPORTDL_IMPORT hiện không được dùng nữa. Các hàm khởi tạo cho mô-đun mở rộng Python hiện phải được khai báo bằng macro PyMODINIT_FUNC mới, trong khi lõi Python thường sẽ sử dụng macro PyAPI_FUNCPyAPI_DATA.

  • Trình thông dịch có thể được biên dịch mà không cần bất kỳ chuỗi tài liệu nào cho các hàm và mô-đun tích hợp bằng cách cung cấp --without-doc-strings cho tập lệnh configure. Điều này làm cho tệp thực thi Python nhỏ hơn khoảng 10%, nhưng cũng có nghĩa là bạn không thể nhận trợ giúp về các phần dựng sẵn của Python. (Đóng góp bởi Gustavo Niemeyer.)

  • Macro PyArg_NoArgs() hiện không được dùng nữa và mã sử dụng macro này sẽ được thay đổi. Đối với Python 2.2 trở lên, bảng định nghĩa phương thức có thể chỉ định cờ METH_NOARGS, báo hiệu rằng không có đối số và sau đó có thể xóa việc kiểm tra đối số. Nếu khả năng tương thích với các phiên bản Python trước 2.2 là quan trọng thì mã có thể sử dụng PyArg_ParseTuple(args, "") thay thế, nhưng việc này sẽ chậm hơn so với sử dụng METH_NOARGS.

  • PyArg_ParseTuple() chấp nhận các ký tự định dạng mới cho các kích cỡ khác nhau của số nguyên không dấu: B cho unsigned char, H cho unsigned short int, I cho unsigned intK cho unsigned long long.

  • Một chức năng mới, PyObject_DelItemString(mapping, char *key) đã được thêm vào dưới dạng viết tắt của PyObject_DelItem(mapping, PyString_New(key)).

  • Các đối tượng tệp bây giờ quản lý bộ đệm chuỗi bên trong của chúng một cách khác nhau, tăng nó theo cấp số nhân khi cần. Điều này dẫn đến các bài kiểm tra điểm chuẩn trong Lib/test/test_bufio.py tăng tốc đáng kể (từ 57 giây lên 1,7 giây, theo một phép đo).

  • Giờ đây, bạn có thể định nghĩa các phương thức lớp và tĩnh cho loại tiện ích mở rộng C bằng cách đặt cờ METH_CLASS hoặc METH_STATIC trong cấu trúc PyMethodDef của phương thức.

  • Python hiện bao gồm một bản sao mã nguồn của trình phân tích cú pháp Expat XML, loại bỏ mọi sự phụ thuộc vào phiên bản hệ thống hoặc cài đặt cục bộ của Expat.

  • Nếu bạn phân bổ động các đối tượng loại trong tiện ích mở rộng của mình, bạn sẽ nhận thấy sự thay đổi trong các quy tắc liên quan đến thuộc tính __module____name__. Tóm lại, bạn sẽ muốn đảm bảo từ điển của loại chứa khóa '__module__'; đặt tên mô-đun thành một phần của tên loại dẫn đến giai đoạn cuối cùng sẽ không còn tác dụng như mong muốn. Để biết thêm chi tiết, hãy đọc tài liệu tham khảo API hoặc nguồn.

Những thay đổi dành riêng cho từng cổng

Hỗ trợ cổng tới OS/2 của IBM sử dụng môi trường thời gian chạy EMX đã được hợp nhất vào cây nguồn Python chính. EMX là lớp mô phỏng POSIX trên API hệ thống OS/2. Cổng Python cho EMX cố gắng hỗ trợ tất cả khả năng giống POSIX được thể hiện trong thời gian chạy EMX và hầu hết đều thành công; fork()fcntl() bị hạn chế bởi các giới hạn của lớp mô phỏng cơ bản. Cổng OS/2 tiêu chuẩn, sử dụng trình biên dịch Visual Age của IBM, cũng được hỗ trợ cho ngữ nghĩa nhập phân biệt chữ hoa chữ thường như một phần của việc tích hợp cổng EMX vào CVS. (Được đóng góp bởi Andrew MacIntyre.)

Trên MacOS, hầu hết các mô-đun hộp công cụ đã được liên kết yếu để cải thiện khả năng tương thích ngược. Điều này có nghĩa là các mô-đun sẽ không còn bị lỗi tải nếu thiếu một quy trình duy nhất trên phiên bản HĐH hiện tại. Thay vào đó, việc gọi thủ tục còn thiếu sẽ đưa ra một ngoại lệ. (Được đóng góp bởi Jack Jansen.)

Các tệp thông số RPM, được tìm thấy trong thư mục Misc/RPM/ trong bản phân phối nguồn Python, đã được cập nhật cho phiên bản 2.3. (Được đóng góp bởi Sean Reifschneider.)

Các nền tảng mới khác hiện được Python hỗ trợ bao gồm AtheOS (http://www.atheos.cx/), GNU/Hurd và OpenVMS.

Những thay đổi và sửa lỗi khác

Như thường lệ, có một loạt các cải tiến và sửa lỗi khác nằm rải rác trong cây nguồn. Tìm kiếm trong nhật ký thay đổi của CVS cho thấy đã có 523 bản vá được áp dụng và 514 lỗi đã được sửa giữa Python 2.2 và 2.3. Cả hai con số đều có khả năng bị đánh giá thấp.

Một số thay đổi đáng chú ý hơn là:

  • Nếu biến môi trường PYTHONINSPECT được đặt, trình thông dịch Python sẽ nhập dấu nhắc tương tác sau khi chạy chương trình Python, như thể Python đã được gọi bằng tùy chọn -i. Biến môi trường có thể được đặt trước khi chạy trình thông dịch Python hoặc có thể được chương trình Python đặt như một phần của quá trình thực thi.

  • Tập lệnh regrtest.py hiện cung cấp cách cho phép "tất cả các tài nguyên ngoại trừ foo." Tên tài nguyên được chuyển đến tùy chọn -u hiện có thể được bắt đầu bằng dấu gạch nối ('-') để có nghĩa là "xóa tài nguyên này". Ví dụ: tùy chọn '-uall,-bsddb' có thể được sử dụng để cho phép sử dụng tất cả các tài nguyên ngoại trừ bsddb.

  • Các công cụ được sử dụng để xây dựng tài liệu hiện hoạt động trong Cygwin cũng như Unix.

  • Mã hoạt động SET_LINENO đã bị xóa. Trước đây, opcode này cần thiết để tạo số dòng trong truy nguyên và hỗ trợ các chức năng theo dõi (ví dụ: pdb). Kể từ Python 1.5, số dòng trong truy nguyên đã được tính toán bằng cơ chế khác hoạt động với "python -O". Đối với Python 2.3, Michael Hudson đã triển khai một sơ đồ tương tự để xác định thời điểm gọi hàm theo dõi, loại bỏ hoàn toàn nhu cầu về SET_LINENO.

    Sẽ rất khó để phát hiện bất kỳ sự khác biệt nào so với mã Python, ngoài việc tăng tốc một chút khi Python chạy mà không có -O.

    Thay vào đó, các tiện ích mở rộng C truy cập vào trường f_lineno của các đối tượng khung nên gọi PyCode_Addr2Line(f->f_code, f->f_lasti). Điều này sẽ có thêm tác dụng làm cho mã hoạt động như mong muốn trong "python -O" trong các phiên bản Python trước đó.

    Một tính năng mới tiện lợi là các hàm theo dõi giờ đây có thể gán cho thuộc tính f_lineno của các đối tượng khung, thay đổi dòng sẽ được thực thi tiếp theo. Lệnh jump đã được thêm vào trình gỡ lỗi pdb để tận dụng tính năng mới này. (Được thực hiện bởi Richie Hindle.)

Chuyển sang Python 2.3

Phần này liệt kê những thay đổi được mô tả trước đây có thể yêu cầu thay đổi mã của bạn:

  • yield bây giờ luôn là một từ khóa; nếu nó được sử dụng làm tên biến trong mã của bạn thì bạn phải chọn một tên khác.

  • Đối với các chuỗi XY, X in Y hiện hoạt động nếu X dài hơn một ký tự.

  • Hàm tạo kiểu int() bây giờ sẽ trả về một số nguyên dài thay vì tăng OverflowError khi một chuỗi hoặc số dấu phẩy động quá lớn để vừa với một số nguyên.

  • Nếu bạn có chuỗi Unicode chứa các ký tự 8 bit, bạn phải khai báo mã hóa của tệp (UTF-8, Latin-1 hoặc bất cứ thứ gì) bằng cách thêm nhận xét vào đầu tệp. Xem phần PEP 263: Mã hóa mã nguồn để biết thêm thông tin.

  • Gọi các phương thức Tcl thông qua _tkinter không còn chỉ trả về chuỗi nữa. Thay vào đó, nếu Tcl trả về các đối tượng khác thì các đối tượng đó sẽ được chuyển đổi thành đối tượng Python tương đương của chúng, nếu có tồn tại hoặc được bao bọc bằng đối tượng _tkinter.Tcl_Obj nếu không tồn tại đối tượng Python tương đương.

  • Các ký tự bát phân và thập lục phân lớn như 0xffffffff hiện kích hoạt FutureWarning. Hiện tại, chúng được lưu trữ dưới dạng số 32 bit và mang lại giá trị âm, nhưng trong Python 2.4, chúng sẽ trở thành số nguyên dài dương.

    Có một số cách để khắc phục cảnh báo này. Nếu bạn thực sự cần một số dương, chỉ cần thêm L vào cuối chữ. Nếu bạn đang cố gắng lấy số nguyên 32 bit với các bit được đặt thấp và trước đó đã sử dụng một biểu thức chẳng hạn như ~(1 << 31), thì có lẽ rõ ràng nhất là bắt đầu với tất cả các bit được đặt và xóa các bit trên mong muốn. Ví dụ: để chỉ xóa bit trên cùng (bit 31), bạn có thể viết 0xffffffffL &~(1L<<31).

  • Bạn không thể tắt xác nhận bằng cách gán cho __debug__ nữa.

  • Hàm Distutils setup() đã nhận được nhiều đối số từ khóa mới như depends. Các phiên bản cũ của Distutils sẽ bị hủy nếu chuyển các từ khóa không xác định. Một giải pháp là kiểm tra sự hiện diện của chức năng get_distutil_options() mới trong setup.py của bạn và chỉ sử dụng các từ khóa mới có phiên bản Distutils hỗ trợ chúng:

    từ lõi nhập khẩu distutils
    
    kw = {'nguồn': 'foo.c', ...}
    nếu hasattr(lõi, 'get_distutil_options'):
        kw['depends'] = ['foo.h']
    ext = Tiện ích mở rộng(**kw)
    
  • Bây giờ, việc sử dụng None làm tên biến sẽ dẫn đến cảnh báo SyntaxWarning.

  • Tên của các loại tiện ích mở rộng được xác định bởi các mô-đun đi kèm với Python hiện chứa mô-đun và '.' ở phía trước tên loại.

Lời cảm ơn

Tác giả xin cảm ơn những người sau đây đã đưa ra gợi ý, chỉnh sửa và hỗ trợ các bản thảo khác nhau của bài viết này: Jeff Bauer, Simon Brunning, Brett Cannon, Michael Chermside, Andrew Dalke, Scott David Daniels, Fred L. Drake, Jr., David Fraser, Kelly Gerber, Raymond Hettinger, Michael Hudson, Chris Lambert, Detlef Lannert, Martin von Löwis, Andrew MacIntyre, Lalo Martins, Chad Netzer, Gustavo Niemeyer, Neal Norwitz, Hans Nowak, Chris Reedy, Francesco Ricciardi, Vinay Sajip, Neil Schenauer, Roman Suzi, Jason Tishler, Just van Rossum.