Có gì mới trong Python 2.4

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.4.1, phát hành ngày 30 tháng 3 năm 2005.

Python 2.4 là bản phát hành cỡ trung bình. Nó không đưa ra nhiều thay đổi như bản Python 2.2 cấp tiến, nhưng giới thiệu nhiều tính năng hơn bản phát hành 2.3 bảo thủ. Các tính năng ngôn ngữ mới quan trọng nhất là trình trang trí hàm và biểu thức trình tạo; hầu hết các thay đổi khác là đối với thư viện chuẩn.

Theo nhật ký thay đổi của CVS, đã có 481 bản vá được áp dụng và 502 lỗi được sửa giữa Python 2.3 và 2.4. Cả hai con số đều có khả năng bị đánh giá thấp.

Bài viết này không cố gắng cung cấp thông số kỹ thuật đầy đủ cho từng tính năng mới mà thay vào đó cung cấp phần giới thiệu ngắn gọn về từng tính năng. Để biết chi tiết đầy đủ, bạn nên tham khảo tài liệu dành cho Python 2.4, chẳng hạn như Python Library Reference và Python Reference Manual. Thông thường, bạn sẽ được giới thiệu đến PEP để biết một tính năng mới cụ thể để giải thích lý do triển khai và thiết kế.

PEP 218: Đối tượng cài sẵn

Python 2.3 đã giới thiệu mô-đun sets. Việc triển khai C các kiểu dữ liệu tập hợp hiện đã được thêm vào lõi Python dưới dạng hai kiểu tích hợp mới, set(iterable)frozenset(iterable). Chúng cung cấp các phép toán tốc độ cao để kiểm tra tư cách thành viên, để loại bỏ các bản sao khỏi chuỗi và cho các phép toán như hợp, giao, sai phân và sai phân đối xứng.

>>> a = set('abracadabra') # form một tập hợp từ một chuỗi
>>> 'z' trong cuộc thử nghiệm  cách thành viên # fast
sai
>>> một chữ cái # unique trong một
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a) # convert trở lại thành một chuỗi
'arbcd'

>>> b = set('alacazam') # form bộ thứ hai
>>> a - b # letters ở a nhưng không ở b
set(['r', 'd', 'b'])
>>> một | b # letters ở a hoặc b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters ở cả a và b
set(['a', 'c'])
>>> a ^ b # letters ở a hoặc b nhưng không phải cả hai
set(['r', 'd', 'b', 'm', 'z', 'l'])

>>> a.add('z') # add một phần tử mới
>>> a.update('wxy') # add nhiều phần tử mới
>>> một
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x') # take một phần tử bị loại
>>> một
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])

Loại frozenset() là phiên bản bất biến của set(). Vì nó không thể thay đổi và có thể băm nên nó có thể được sử dụng làm khóa từ điển hoặc là thành viên của bộ khác.

Mô-đun sets vẫn còn trong thư viện chuẩn và có thể hữu ích nếu bạn muốn phân lớp các lớp Set hoặc ImmutableSet. Hiện tại không có kế hoạch ngừng sử dụng mô-đun này.

Xem thêm

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

Được đề xuất ban đầu bởi Greg Wilson và cuối cùng được thực hiện bởi Raymond Hettinger.

PEP 237: Thống nhất số nguyên dài và số nguyên

Quá trình chuyển đổi kéo dài cho PEP này, bắt đầu bằng Python 2.2, tiến thêm một bước nữa trong Python 2.4. Trong 2.3, một số thao tác số nguyên nhất định sẽ hoạt động khác sau khi hợp nhất int/long đã kích hoạt cảnh báo FutureWarning và trả về các giá trị được giới hạn ở 32 hoặc 64 bit (tùy thuộc vào nền tảng của bạn). Trong phiên bản 2.4, những biểu thức này không còn đưa ra cảnh báo nữa mà thay vào đó tạo ra một kết quả khác thường là số nguyên dài.

Các biểu thức có vấn đề chủ yếu là dịch chuyển trái và các hằng số thập lục phân và bát phân dài. Ví dụ: 2 << 32 dẫn đến cảnh báo ở phiên bản 2.3, đánh giá là 0 trên nền tảng 32 bit. Trong Python 2.4, biểu thức này hiện trả về câu trả lời đúng, 8589934592.

Xem thêm

PEP 237 - Hợp nhất số nguyên dài và số nguyên

Zz000zz gốc được viết bởi Moshe Zadka và GvR. Những thay đổi cho phiên bản 2.4 được thực hiện bởi Kalle Svensson.

PEP 289: Biểu thức tạo

Tính năng lặp được giới thiệu trong Python 2.2 và mô-đun itertools giúp viết chương trình lặp qua các tập dữ liệu lớn dễ dàng hơn mà không cần phải đặt toàn bộ dữ liệu vào bộ nhớ cùng một lúc. Việc hiểu danh sách không phù hợp lắm với bức tranh này vì chúng tạo ra một đối tượng danh sách Python chứa tất cả các mục. Điều này chắc chắn sẽ kéo tất cả các đối tượng vào bộ nhớ, đây có thể là một vấn đề nếu tập dữ liệu của bạn rất lớn. Khi cố gắng viết một chương trình có kiểu dáng chức năng, việc viết một cái gì đó như :: là điều tự nhiên.

links = [liên kết cho liên kết trong get_all_links() nếu không phải link.followed]
cho liên kết trong liên kết:
    ...

thay vì

cho liên kết trong get_all_links():
    nếu link.followed:
        tiếp tục
    ...

Biểu mẫu đầu tiên ngắn gọn hơn và có lẽ dễ đọc hơn, nhưng nếu bạn đang xử lý một số lượng lớn đối tượng liên kết thì bạn phải viết biểu mẫu thứ hai để tránh có tất cả các đối tượng liên kết trong bộ nhớ cùng một lúc.

Các biểu thức của trình tạo hoạt động tương tự như việc hiểu danh sách nhưng không cụ thể hóa toàn bộ danh sách; thay vào đó họ tạo một trình tạo sẽ trả về từng phần tử một. Ví dụ trên có thể được viết là:

links = (liên kết cho liên kết trong get_all_links() nếu không phải link.followed)
cho liên kết trong liên kết:
    ...

Các biểu thức của trình tạo luôn phải được viết bên trong dấu ngoặc đơn, như trong ví dụ trên. Các dấu ngoặc đơn báo hiệu một lệnh gọi hàm cũng được tính, vì vậy nếu bạn muốn tạo một trình vòng lặp sẽ được chuyển ngay đến một hàm, bạn có thể viết:

in tổng(obj.count cho obj trong list_all_objects())

Các biểu thức của trình tạo khác với việc hiểu danh sách theo nhiều cách nhỏ khác nhau. Đáng chú ý nhất là biến vòng lặp (obj trong ví dụ trên) không thể truy cập được bên ngoài biểu thức trình tạo. Việc hiểu danh sách để lại biến được gán cho giá trị cuối cùng của nó; các phiên bản tương lai của Python sẽ thay đổi điều này, làm cho việc hiểu danh sách khớp với các biểu thức của trình tạo về mặt này.

Xem thêm

PEP 289 - Biểu thức tạo

Được đề xuất bởi Raymond Hettinger và được thực hiện bởi Jiwon Seo với những nỗ lực ban đầu do Hye-Shik Chang chỉ đạo.

PEP 292: Thay thế chuỗi đơn giản hơn

Một số lớp mới trong thư viện chuẩn cung cấp cơ chế thay thế để thay thế các biến thành chuỗi; kiểu thay thế này có thể tốt hơn cho các ứng dụng mà người dùng chưa qua đào tạo cần chỉnh sửa mẫu.

Cách thông thường để thay thế các biến theo tên là toán tử %:

>>> '%(page)i: %(title)s' % {'page':2, 'title': 'Điều tuyệt vời nhất'}
'2: Thời đại tuyệt vời nhất'

Khi viết chuỗi mẫu, bạn có thể dễ dàng quên i hoặc s sau dấu ngoặc đơn đóng. Đây không phải là vấn đề lớn nếu mẫu nằm trong mô-đun Python vì bạn chạy mã, nhận được "Ký tự định dạng không được hỗ trợ" ValueError và khắc phục sự cố. Tuy nhiên, hãy xem xét một ứng dụng như Mailman trong đó các chuỗi mẫu hoặc bản dịch đang được chỉnh sửa bởi những người dùng không biết về ngôn ngữ Python. Cú pháp của chuỗi định dạng rất phức tạp để giải thích cho những người dùng như vậy và nếu họ mắc lỗi thì rất khó để cung cấp phản hồi hữu ích cho họ.

PEP 292 thêm lớp Template vào mô-đun string sử dụng $ để biểu thị sự thay thế

>>> nhập chuỗi
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: Thời đại tuyệt vời nhất'

Nếu thiếu một khóa trong từ điển, phương thức substitute() sẽ đưa ra KeyError. Ngoài ra còn có một phương pháp safe_substitute() bỏ qua các khóa bị thiếu

>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $tiêu đề'

Xem thêm

PEP 292 - Thay thế chuỗi đơn giản hơn

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

PEP 318: Trang trí cho hàm và phương thức

Python 2.2 đã mở rộng mô hình đối tượng của Python bằng cách thêm các phương thức tĩnh và phương thức lớp, nhưng nó không mở rộng cú pháp của Python để cung cấp bất kỳ cách mới nào để xác định các phương thức tĩnh hoặc lớp. Thay vào đó, bạn phải viết câu lệnh def theo cách thông thường và chuyển phương thức kết quả cho hàm staticmethod() hoặc classmethod() để gói hàm này thành một phương thức của loại mới. Mã của bạn sẽ trông như thế này:

lớp C:
   def meth (cls):
       ...

   meth = classmethod(meth) tên # Rebind thành phương thức lớp được gói gọn

Nếu phương thức này quá dài, bạn sẽ dễ bỏ lỡ hoặc quên lệnh gọi classmethod() sau phần thân hàm.

Mục đích luôn là thêm một số cú pháp để làm cho những định nghĩa như vậy dễ đọc hơn, nhưng tại thời điểm phát hành phiên bản 2.2, cú pháp tốt vẫn chưa rõ ràng. Ngày nay, cú pháp tốt still không rõ ràng nhưng người dùng đang yêu cầu quyền truy cập vào tính năng này dễ dàng hơn; một tính năng cú pháp mới đã được thêm vào để đáp ứng nhu cầu này.

Tính năng mới được gọi là "trang trí chức năng". Cái tên này xuất phát từ ý tưởng rằng classmethod(), staticmethod() và những người bạn đang lưu trữ thông tin bổ sung về một đối tượng hàm; chúng là các chức năng decorating với nhiều chi tiết hơn.

Ký hiệu mượn từ Java và sử dụng ký tự '@' làm chỉ báo. Sử dụng cú pháp mới, ví dụ trên sẽ được viết:

lớp C:

   @classmethod
   def meth (cls):
       ...

@classmethod là viết tắt của nhiệm vụ meth=classmethod(meth). Tổng quát hơn, nếu bạn có những điều sau đây:

@A
@B
@C
định nghĩa f():
    ...

Nó tương đương với mã trang trí trước sau:

chắc chắn f(): ...
f = A(B(C(f)))

Các trình trang trí phải xuất hiện trước định nghĩa hàm, một trình trang trí trên mỗi dòng và không được nằm trên cùng một dòng với câu lệnh def, nghĩa là @A def f(): ... là bất hợp pháp. Bạn chỉ có thể trang trí các định nghĩa hàm, ở cấp mô-đun hoặc bên trong một lớp; bạn không thể trang trí các định nghĩa lớp.

Trình trang trí chỉ là một hàm lấy hàm được trang trí làm đối số và trả về cùng một hàm hoặc một số đối tượng mới. Giá trị trả về của trình trang trí không cần phải gọi được (mặc dù thông thường là như vậy), trừ khi các trình trang trí khác sẽ được áp dụng cho kết quả. Thật dễ dàng để viết trang trí của riêng bạn. Ví dụ đơn giản sau đây chỉ đặt một thuộc tính trên đối tượng hàm:

>>> trang trí def(func):
... func.attr = 'được trang trí'
... trả lại chức năng
...
>>> @deco
... def f(): vượt qua
...
>>> f
<hàm f tại 0x402ef0d4>
>>> f.attr
'được trang trí'
>>>

Là một ví dụ thực tế hơn một chút, trình trang trí sau đây sẽ kiểm tra xem đối số được cung cấp có phải là số nguyên hay không:

def require_int (func):
    trình bao bọc def (arg):
        khẳng định isinstance(arg, int)
        trả về func(arg)

    giấy gói trả lại

@require_int
def p1 (arg):
    in tranh luận

@require_int
định nghĩa p2(arg):
    in arg*2

Một ví dụ trong PEP 318 chứa một phiên bản thú vị hơn của ý tưởng này cho phép bạn vừa chỉ định loại được yêu cầu vừa kiểm tra loại được trả về.

Các hàm trang trí có thể nhận các đối số. Nếu các đối số được cung cấp, hàm trang trí của bạn sẽ chỉ được gọi với các đối số đó và phải trả về một hàm trang trí mới; hàm này phải nhận một hàm duy nhất và trả về một hàm, như được mô tả trước đây. Nói cách khác, @A @B @C(args) trở thành:

chắc chắn f(): ...
_deco = C(args)
f = A(B(_deco(f)))

Làm đúng điều này có thể hơi khó khăn, nhưng nó không quá khó.

Một thay đổi nhỏ có liên quan làm cho thuộc tính func_name của hàm có thể ghi được. Thuộc tính này được sử dụng để hiển thị tên hàm trong traceback, vì vậy người trang trí nên thay đổi tên của bất kỳ hàm mới nào được xây dựng và trả về.

Xem thêm

PEP 318 - Trang trí cho hàm, phương thức và lớp

Được viết bởi Kevin D. Smith, Jim Jewett và Skip Montanaro. Một số người đã viết các bản vá triển khai các trình trang trí chức năng, nhưng bản vá thực sự được kiểm tra là bản vá #979728, được viết bởi Mark Russell.

https://wiki.python.org/moin/PythonDecoratorLibrary

Trang Wiki này chứa một số ví dụ về trang trí.

PEP 322: Lặp lại ngược lại

Một hàm tích hợp mới, reversed(seq), nhận một chuỗi và trả về một trình vòng lặp lặp qua các phần tử của chuỗi theo thứ tự ngược lại.

>>> cho i  vị trí đảo ngược(xrange(1,4)):
... in tôi
...
3
2
1

So với việc cắt mở rộng, chẳng hạn như range(1,4)[::-1], reversed() dễ đọc hơn, chạy nhanh hơn và sử dụng ít bộ nhớ hơn đáng kể.

Lưu ý rằng reversed() chỉ chấp nhận các chuỗi chứ không chấp nhận các trình vòng lặp tùy ý. Nếu bạn muốn đảo ngược một trình vòng lặp, trước tiên hãy chuyển đổi nó thành một danh sách có list().

>>> đầu vào = open('/etc/passwd', 'r')
>>> cho dòng bị đảo ngược(danh sách(đầu vào)):
... dòng in
...
root:*:0:0:Quản trị viên hệ thống:/var/root:/bin/tcsh
  ...

Xem thêm

PEP 322 - Lặp lại ngược

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

PEP 324: Mô-đun quy trình con mới

Thư viện chuẩn cung cấp một số cách để thực thi một quy trình con, cung cấp các tính năng khác nhau và mức độ phức tạp khác nhau. os.system(command) rất dễ sử dụng nhưng chậm (nó chạy một tiến trình shell thực thi lệnh) và nguy hiểm (bạn phải cẩn thận khi thoát khỏi siêu ký tự của shell). Mô-đun popen2 cung cấp các lớp có thể nắm bắt đầu ra tiêu chuẩn và lỗi tiêu chuẩn từ quy trình con, nhưng việc đặt tên gây nhầm lẫn. Mô-đun subprocess sẽ giải quyết vấn đề này, cung cấp giao diện hợp nhất cung cấp tất cả các tính năng mà bạn có thể cần.

Thay vì tập hợp các lớp của popen2, subprocess chứa một lớp duy nhất gọi là subprocess.Popen mà hàm tạo của nó hỗ trợ một số đối số từ khóa khác nhau.

lớp Popen(args, bufsize=0,executable=None,
            stdin=Không , stdout=Không , stderr=Không ,
            preexec_fn=Không , close_fds=Sai, shell=Sai,
            cwd=Không , env=Không , Universal_newlines=False,
            startupinfo=Không , Creationflags=0):

args thường là một chuỗi các chuỗi sẽ là đối số cho chương trình được thực thi dưới dạng quy trình con. (Nếu đối số shell là đúng, args có thể là một chuỗi sau đó sẽ được chuyển tới shell để giải thích, giống như os.system().)

stdin, stdoutstderr chỉ định luồng đầu vào, đầu ra và lỗi của quy trình con sẽ là gì. Bạn có thể cung cấp một đối tượng tệp hoặc một bộ mô tả tệp hoặc bạn có thể sử dụng hằng số subprocess.PIPE để tạo một đường dẫn giữa quy trình con và quy trình gốc.

Hàm tạo có một số tùy chọn hữu ích:

  • close_fds yêu cầu đóng tất cả các bộ mô tả tệp trước khi chạy quy trình con.

  • cwd chỉ định thư mục làm việc trong đó quy trình con sẽ được thực thi (mặc định là bất kỳ thư mục làm việc nào của cha mẹ).

  • env là một từ điển chỉ định các biến môi trường.

  • preexec_fn là một hàm được gọi trước khi trẻ khởi động.

  • universal_newlines mở đầu vào và đầu ra của trẻ bằng tính năng universal newlines của Python.

Sau khi tạo phiên bản Popen, bạn có thể gọi phương thức wait() của nó để tạm dừng cho đến khi quy trình con thoát ra, poll() để kiểm tra xem nó có thoát mà không tạm dừng hay không, hoặc communicate(data) để gửi chuỗi data đến đầu vào tiêu chuẩn của quy trình con. communicate(data) sau đó đọc bất kỳ dữ liệu nào mà quy trình con đã gửi đến đầu ra tiêu chuẩn hoặc lỗi tiêu chuẩn của nó, trả về một bộ dữ liệu (stdout_data, stderr_data).

call() là một phím tắt chuyển các đối số của nó tới hàm tạo Popen, đợi lệnh hoàn thành và trả về mã trạng thái của quy trình con. Nó có thể hoạt động như một chất tương tự an toàn hơn với os.system():

sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
nếu sts == 0:
    # Success
    ...
khác:
    # dpkg trả về lỗi
    ...

Lệnh được gọi mà không cần sử dụng shell. Nếu bạn thực sự muốn sử dụng shell, bạn có thể thêm shell=True làm đối số từ khóa và cung cấp một chuỗi thay vì một chuỗi

sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)

Zz001zz lấy nhiều ví dụ khác nhau về mã shell và mã Python, đồng thời cho biết cách dịch chúng sang mã Python sử dụng subprocess. Rất nên đọc phần này của PEP.

Xem thêm

PEP 324 - quy trình con - Mô-đun quy trình mới

Được viết và thực hiện bởi Peter Åstrand, với sự hỗ trợ của Fredrik Lundh và những người khác.

PEP 327: Kiểu dữ liệu thập phân

Python luôn hỗ trợ các số dấu phẩy động (FP), dựa trên kiểu C double cơ bản, dưới dạng kiểu dữ liệu. Tuy nhiên, trong khi hầu hết các ngôn ngữ lập trình đều cung cấp loại dấu phẩy động, nhiều người (thậm chí cả lập trình viên) không biết rằng các số dấu phẩy động không biểu thị chính xác một số phân số thập phân nhất định. Loại Decimal mới có thể biểu thị các phân số này một cách chính xác, lên đến giới hạn độ chính xác do người dùng chỉ định.

Tại sao cần thập phân?

Những hạn chế phát sinh từ cách biểu diễn được sử dụng cho số dấu phẩy động. Số FP được tạo thành từ ba thành phần:

  • Dấu hiệu là dương hoặc âm.

  • Phần định trị, là số nhị phân có một chữ số, theo sau là phần phân số. Ví dụ: 1.01 trong ký hiệu cơ số 2 là 1 + 0/2 + 1/4 hoặc 1,25 trong ký hiệu thập phân.

  • Số mũ, cho biết vị trí của dấu thập phân trong số được biểu thị.

Ví dụ: số 1,25 có dấu dương, giá trị mantissa là 1,01 (ở dạng nhị phân) và số mũ là 0 (không cần dịch chuyển dấu thập phân). Số 5 có cùng dấu và cùng số mũ nhưng số mũ là 2 vì số mũ được nhân với 4 (2 lũy thừa của số mũ 2); 1,25 * 4 bằng 5.

Các hệ thống hiện đại thường cung cấp hỗ trợ dấu phẩy động tuân theo tiêu chuẩn gọi là IEEE 754. Loại double của C thường được triển khai dưới dạng số IEEE 754 64 bit, sử dụng 52 bit không gian cho phần định trị. Điều này có nghĩa là các số chỉ có thể được xác định với độ chính xác 52 bit. Nếu bạn đang cố gắng biểu diễn các số có phần mở rộng lặp lại vô tận thì phần mở rộng sẽ bị cắt sau 52 bit. Thật không may, hầu hết phần mềm cần tạo đầu ra ở cơ số 10 và các phân số phổ biến trong cơ số 10 thường lặp lại số thập phân ở dạng nhị phân. Ví dụ: 1,1 thập phân là 1.0001100110011 ... nhị phân; .1 = 1/16 + 1/32 + 1/256 cộng với vô số số hạng bổ sung. IEEE 754 phải loại bỏ số thập phân lặp lại vô hạn đó sau 52 chữ số, do đó cách biểu diễn hơi không chính xác.

Đôi khi bạn có thể thấy sự thiếu chính xác này khi số được in:

>>> 1.1
1.1000000000000001

Sự thiếu chính xác không phải lúc nào cũng hiển thị khi bạn in số vì chuyển đổi FP sang chuỗi thập phân được cung cấp bởi thư viện C và hầu hết các thư viện C đều cố gắng tạo ra đầu ra hợp lý. Tuy nhiên, ngay cả khi nó không được hiển thị thì độ chính xác vẫn còn đó và các thao tác tiếp theo có thể làm cho lỗi trở nên nghiêm trọng hơn.

Đối với nhiều ứng dụng, điều này không thành vấn đề. Nếu tôi vẽ các điểm và hiển thị chúng trên màn hình của mình, thì sự khác biệt giữa 1,1 và 1,1000000000000001 là quá nhỏ để có thể nhìn thấy được. Các báo cáo thường giới hạn kết quả đầu ra ở một số vị trí thập phân nhất định và nếu bạn làm tròn số đó đến hai, ba hoặc thậm chí tám chữ số thập phân thì lỗi sẽ không bao giờ rõ ràng. Tuy nhiên, đối với các ứng dụng quan trọng, việc triển khai các quy trình số học tùy chỉnh của riêng bạn sẽ tốn rất nhiều công sức.

Do đó, loại Decimal đã được tạo.

Loại Decimal

Một mô-đun mới, decimal, đã được thêm vào thư viện chuẩn của Python. Nó chứa hai lớp, DecimalContext. Các phiên bản Decimal đại diện cho các số và các phiên bản Context được sử dụng để bao bọc các cài đặt khác nhau như độ chính xác và chế độ làm tròn mặc định.

Các phiên bản Decimal là bất biến, giống như số nguyên Python và số FP thông thường; một khi nó đã được tạo, bạn không thể thay đổi giá trị mà một phiên bản thể hiện. Các phiên bản Decimal có thể được tạo từ số nguyên hoặc chuỗi

>>> nhập số thập phân
>>> thập phân.Decimal(1972)
Thập phân("1972")
>>> thập phân.Decimal("1.1")
Thập phân("1.1")

Bạn cũng có thể cung cấp các bộ chứa dấu hiệu, phần định trị được biểu thị dưới dạng bộ các chữ số thập phân và số mũ:

>>> thập phân.Decimal((1, (1, 4, 7, 5), -2))
Thập phân("-14.75")

Lưu ý thận trọng: bit dấu là giá trị Boolean, vì vậy 0 là dương và 1 là âm.

Việc chuyển đổi từ số dấu phẩy động gặp một chút vấn đề: số FP đại diện cho 1,1 có nên chuyển thành số thập phân cho chính xác 1,1 hay cho 1,1 cộng với bất kỳ điểm không chính xác nào được đưa ra không? Quyết định là tránh vấn đề này và loại bỏ việc chuyển đổi như vậy ra khỏi API. Thay vào đó, bạn nên chuyển đổi số dấu phẩy động thành một chuỗi với độ chính xác mong muốn và chuyển chuỗi đó tới hàm tạo Decimal:

>>> f = 1,1
>>> thập phân.Decimal(str(f))
Thập phân("1.1")
>>> thập phân.Decimal('%.12f' % f)
Thập phân ("1.100000000000")

Sau khi có phiên bản Decimal, bạn có thể thực hiện các phép toán thông thường trên chúng. Một hạn chế: phép lũy thừa yêu cầu số mũ nguyên:

>>> a = thập phân.Decimal('35.72')
>>> b = thập phân.Decimal('1.73')
>>> a+b
Thập phân("37.45")
>>> a-b
Thập phân("33.99")
>>> a*b
Thập phân("61.7956")
>>> a/b
Thập phân ("20,64739884393063583815028902")
>>> một ** 2
Thập phân("1275.9184")
>>> a**b
Traceback (cuộc gọi gần đây nhất):
  ...
thập phân.InvalidOperation: x ** (không nguyên)

Bạn có thể kết hợp các phiên bản Decimal với số nguyên, nhưng không thể kết hợp với số dấu phẩy động:

>>> một + 4
Thập phân("39.72")
>>> a + 4,5
Traceback (cuộc gọi gần đây nhất):
  ...
TypeError: Bạn chỉ có thể tương tác Decimal với các kiểu dữ liệu int, long hoặc Decimal.
>>>

Bạn có thể sử dụng số Decimal với mô-đun mathcmath nhưng lưu ý rằng chúng sẽ ngay lập tức được chuyển đổi thành số dấu phẩy động trước khi thực hiện thao tác, dẫn đến có thể mất độ chính xác và độ chính xác. Bạn cũng sẽ nhận được số dấu phẩy động thông thường chứ không phải Decimal.

>>> nhập toán, cmath
>>> d = thập phân.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j

Các phiên bản Decimal có phương thức sqrt() trả về Decimal, nhưng nếu bạn cần những thứ khác như hàm lượng giác thì bạn sẽ phải triển khai chúng.

>>> d.sqrt()
Thập phân ("351364.1828820134592177245001")

Loại Context

Các phiên bản của lớp Context gói gọn một số cài đặt cho các phép toán thập phân:

  • prec là độ chính xác, số chữ số thập phân.

  • rounding chỉ định chế độ làm tròn. Mô-đun decimal có các hằng số cho các khả năng khác nhau: ROUND_DOWN, ROUND_CEILING, ROUND_HALF_EVEN và nhiều loại khác.

  • traps là một từ điển chỉ rõ điều gì sẽ xảy ra khi gặp phải một số điều kiện lỗi nhất định: hoặc một ngoại lệ được đưa ra hoặc một giá trị được trả về. Một số ví dụ về điều kiện lỗi là chia cho 0, mất độ chính xác và tràn.

Có sẵn bối cảnh mặc định theo luồng cục bộ bằng cách gọi getcontext(); bạn có thể thay đổi các thuộc tính của ngữ cảnh này để thay đổi độ chính xác mặc định, làm tròn hoặc xử lý bẫy. Ví dụ sau đây cho thấy tác động của việc thay đổi độ chính xác của ngữ cảnh mặc định:

>>> thập phân.getcontext().prec
28
>>> thập phân.Decimal(1) / thập phân.Decimal(7)
Thập phân ("0,1428571428571428571428571429")
>>> thập phân.getcontext().prec = 9
>>> thập phân.Decimal(1) / thập phân.Decimal(7)
Thập phân("0.142857143")

Có thể lựa chọn hành động mặc định cho các điều kiện lỗi; mô-đun có thể trả về một giá trị đặc biệt như vô cực hoặc không phải số hoặc có thể đưa ra các ngoại lệ:

>>> thập phân.Decimal(1) / thập phân.Decimal(0)
Traceback (cuộc gọi gần đây nhất):
  ...
thập phân.DivisionByZero: x / 0
>>> thập phân.getcontext().traps[decimal.DivisionByZero] = Sai
>>> thập phân.Decimal(1) / thập phân.Decimal(0)
Thập phân("Vô cực")
>>>

Phiên bản Context cũng có nhiều phương pháp khác nhau để định dạng số như to_eng_string()to_sci_string().

Để biết thêm thông tin, hãy xem tài liệu dành cho mô-đun decimal, bao gồm hướng dẫn bắt đầu nhanh và tài liệu tham khảo.

Xem thêm

PEP 327 - Kiểu dữ liệu thập phân

Được viết bởi Facundo Batista và được thực hiện bởi Facundo Batista, Eric Price, Raymond Hettinger, Aahz và Tim Peters.

http://www.lahey.com/float.htm

Bài viết sử dụng mã Fortran để minh họa nhiều vấn đề mà tính không chính xác của dấu phẩy động có thể gây ra.

https://speleotrove.com/decimal/

Mô tả cách biểu diễn dựa trên số thập phân. Cách biểu diễn này đang được đề xuất làm tiêu chuẩn và làm cơ sở cho kiểu thập phân Python mới. Phần lớn tài liệu này được viết bởi Mike Cowlishaw, người thiết kế ngôn ngữ Rexx.

PEP 328: Nhập nhiều dòng

Một thay đổi về ngôn ngữ là một chỉnh sửa nhỏ về cú pháp nhằm mục đích giúp việc nhập nhiều tên từ một mô-đun trở nên dễ dàng hơn. Trong câu lệnh from module import names, names là một chuỗi các tên được phân tách bằng dấu phẩy. Nếu chuỗi rất dài, bạn có thể viết nhiều lần nhập từ cùng một mô-đun hoặc bạn có thể sử dụng dấu gạch chéo ngược để thoát khỏi các kết thúc dòng như thế này:

từ SimpleXMLRPCServer nhập SimpleXMLRPCServer,\
            SimpleXMLRPCRequestHandler,\
            CGIXMLRPCRequestHandler,\
            giải quyết_dotted_attribute

Thay đổi cú pháp trong Python 2.4 chỉ cho phép đặt tên trong ngoặc đơn. Python bỏ qua các dòng mới trong biểu thức được ngoặc đơn, do đó dấu gạch chéo ngược không còn cần thiết nữa

từ việc nhập SimpleXMLRPCServer (SimpleXMLRPCServer,
                                SimpleXMLRPCRequestHandler,
                                CGIXMLRPCRequestHandler,
                                giải quyết_dotted_attribute)

PEP cũng đề xuất rằng tất cả các câu lệnh import đều được nhập tuyệt đối, với ký tự . ở đầu để biểu thị mức nhập tương đối. Phần PEP này chưa được triển khai cho Python 2.4 nhưng đã được hoàn thiện cho Python 2.5.

Xem thêm

PEP 328 - Nhập khẩu: Nhiều dòng và Tuyệt đối/Tương đối

Được viết bởi Aahz. Nhập khẩu nhiều dòng được thực hiện bởi Dima Dorfman.

PEP 331: Chuyển đổi chuỗi/nổi độc lập với miền địa phương

Các mô-đun locale cho phép phần mềm Python chọn các quy ước chuyển đổi và hiển thị khác nhau được bản địa hóa cho một quốc gia hoặc ngôn ngữ cụ thể. Tuy nhiên, mô-đun này đã cẩn thận để không thay đổi ngôn ngữ số vì các hàm khác nhau trong quá trình triển khai của Python yêu cầu ngôn ngữ số vẫn được đặt thành ngôn ngữ 'C'. Điều này thường là do mã đang sử dụng hàm atof() của thư viện C.

Tuy nhiên, việc không đặt ngôn ngữ số sẽ gây rắc rối cho các tiện ích mở rộng sử dụng thư viện C của bên thứ ba vì chúng không có ngôn ngữ chính xác được đặt. Ví dụ thúc đẩy là GTK+, tiện ích giao diện người dùng của nó không hiển thị số ở ngôn ngữ hiện tại.

Giải pháp được mô tả trong PEP là thêm ba hàm mới vào Python API để thực hiện chuyển đổi chỉ dành cho ASCII, bỏ qua cài đặt ngôn ngữ:

  • PyOS_ascii_strtod(str, ptr)PyOS_ascii_atof(str, ptr) đều chuyển đổi một chuỗi thành C double.

  • PyOS_ascii_formatd(buffer, buf_len, format, d) chuyển đổi double thành chuỗi ASCII.

Mã cho các hàm này đến từ thư viện GLib (https://developer-old.gnome.org/glib/2.26/), các nhà phát triển của thư viện này đã vui lòng cấp lại các hàm liên quan và tặng chúng cho Python Software Foundation. Mô-đun locale hiện có thể thay đổi ngôn ngữ số, cho phép các tiện ích mở rộng như GTK+ tạo ra kết quả chính xác.

Xem thêm

PEP 331 - Chuyển đổi chuỗi/chuỗi độc lập với miền địa phương

Được viết bởi Christian R. Reis và được thực hiện bởi Gustavo Carneiro.

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

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

  • Trang trí cho các hàm và phương thức đã được thêm vào (PEP 318).

  • Các loại set()frozenset() tích hợp đã được thêm vào (PEP 218). Các phần mềm tích hợp mới khác bao gồm chức năng reversed(seq) (PEP 322).

  • Các biểu thức của trình tạo đã được thêm vào (PEP 289).

  • Một số biểu thức số nhất định không còn trả về các giá trị bị giới hạn ở 32 hoặc 64 bit (PEP 237).

  • Bây giờ bạn có thể đặt dấu ngoặc đơn xung quanh danh sách tên trong câu lệnh from module import names (PEP 328).

  • Phương thức dict.update() hiện chấp nhận các dạng đối số giống như hàm tạo dict. Điều này bao gồm mọi ánh xạ, mọi cặp khóa/giá trị có thể lặp lại và đối số từ khóa. (Được đóng góp bởi Raymond Hettinger.)

  • Các phương thức chuỗi ljust(), rjust()center() hiện có một đối số tùy chọn để chỉ định ký tự điền không phải là khoảng trắng. (Được đóng góp bởi Raymond Hettinger.)

  • Chuỗi cũng có được phương thức rsplit() hoạt động giống như phương thức split() nhưng tách ra từ cuối chuỗi. (Được đóng góp bởi Sean Reifschneider.)

    >>> 'www.python.org'.split('.', 1)
    ['www', 'python.org']
    'www.python.org'.rsplit('.', 1)
    ['www.python', 'tổ chức']
    
  • Ba tham số từ khóa, cmp, keyreverse, đã được thêm vào phương thức danh sách sort(). Các tham số này làm cho một số cách sử dụng phổ biến của sort() trở nên đơn giản hơn. Tất cả các tham số này là tùy chọn.

    Đối với tham số cmp, giá trị phải là hàm so sánh nhận hai tham số và trả về -1, 0 hoặc +1 tùy thuộc vào cách so sánh các tham số. Chức năng này sau đó sẽ được sử dụng để sắp xếp danh sách. Trước đây đây là tham số duy nhất có thể được cung cấp cho sort().

    key phải là hàm một tham số nhận phần tử danh sách và trả về khóa so sánh cho phần tử đó. Danh sách sau đó được sắp xếp bằng cách sử dụng các phím so sánh. Ví dụ sau sắp xếp danh sách không phân biệt chữ hoa chữ thường:

    >>> L = ['A', 'b', 'c', 'D']
    >>> Sắp xếp L.sort() # Case-sensitive
    >>> L
    ['A', 'D', 'b', 'c']
    >>> Tham số 'key' # Using để sắp xếp danh sách
    >>> L.sort(key=lambda x: x.low())
    >>> L
    ['A', 'b', 'c', 'D']
    >>> cách # Old-fashioned
    >>> L.sort(cmp=lambda x,y: cmp(x.low(), y.low()))
    >>> L
    ['A', 'b', 'c', 'D']
    

    Ví dụ cuối cùng, sử dụng tham số cmp, là cách cũ để thực hiện sắp xếp không phân biệt chữ hoa chữ thường. Nó hoạt động nhưng chậm hơn so với sử dụng tham số key. Việc sử dụng key gọi phương thức lower() một lần cho mỗi phần tử trong danh sách trong khi sử dụng cmp sẽ gọi nó hai lần cho mỗi lần so sánh, do đó, sử dụng key sẽ tiết kiệm được việc gọi phương thức lower().

    Đối với các hàm khóa đơn giản và hàm so sánh, thường có thể tránh được biểu thức lambda bằng cách sử dụng phương thức không liên kết thay thế. Ví dụ: cách sắp xếp không phân biệt chữ hoa chữ thường ở trên được viết tốt nhất là:

    >>> L.sort(key=str.low)
    >>> L
    ['A', 'b', 'c', 'D']
    

    Cuối cùng, tham số reverse nhận giá trị Boolean. Nếu giá trị đúng, danh sách sẽ được sắp xếp theo thứ tự ngược lại. Thay vì L.sort(); L.reverse(), giờ đây bạn có thể viết L.sort(reverse=True).

    Kết quả phân loại hiện nay được đảm bảo ổn định. Điều này có nghĩa là hai mục có khóa bằng nhau sẽ được trả về theo cùng thứ tự như chúng được nhập vào. Ví dụ: bạn có thể sắp xếp danh sách những người theo tên, sau đó sắp xếp danh sách theo độ tuổi, dẫn đến danh sách được sắp xếp theo độ tuổi trong đó những người có cùng độ tuổi được sắp xếp theo thứ tự tên.

    (Tất cả các thay đổi đối với sort() đều do Raymond Hettinger đóng góp.)

  • Có một hàm tích hợp mới sorted(iterable) hoạt động giống như phương thức list.sort() tại chỗ nhưng có thể được sử dụng trong biểu thức. Sự khác biệt là:

  • đầu vào có thể là bất kỳ lần lặp nào;

  • một bản sao mới được tạo thành được sắp xếp, giữ nguyên bản gốc; và

  • biểu thức trả về bản sao được sắp xếp mới

    >>> L = [9,7,8,3,2,4,1,6,5]
    >>> [10+i cho i trong được sắp xếp(L)] # usable trong phần hiểu danh sách
    [11, 12, 13, 14, 15, 16, 17, 18, 19]
    >>> L # original được giữ nguyên
    [9,7,8,3,2,4,1,6,5]
    >>> được sắp xếp('Monty Python') # any iterable có thể là đầu vào
    [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']
    
    >>> # List nội dung của một lệnh được sắp xếp theo các giá trị khóa
    >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)
    >>> cho k, v trong được sắp xếp(colormap.iteritems()):
    ... in k, v
    ...
    đen 4
    màu xanh 2
    xanh 3
    màu đỏ 1
    màu vàng 5
    

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

  • Các phép toán số nguyên sẽ không còn kích hoạt OverflowWarning nữa. Cảnh báo OverflowWarning sẽ biến mất trong Python 2.5.

  • Trình thông dịch đã có một công tắc mới, -m, nhận tên, tìm kiếm mô-đun tương ứng trên sys.path và chạy mô-đun đó dưới dạng tập lệnh. Ví dụ: bây giờ bạn có thể chạy trình lược tả Python bằng python -m profile. (Được đóng góp bởi Nick Coghlan.)

  • Các hàm eval(expr, globals, locals)execfile(filename, globals, locals) cũng như câu lệnh exec hiện chấp nhận mọi loại ánh xạ cho tham số locals. Trước đây đây phải là một từ điển Python thông thường. (Được đóng góp bởi Raymond Hettinger.)

  • Hàm tích hợp zip()itertools.izip() hiện trả về một danh sách trống nếu được gọi không có đối số. Trước đây họ đã đưa ra một ngoại lệ TypeError. Điều này làm cho chúng phù hợp hơn để sử dụng với danh sách đối số có độ dài thay đổi

    >>> chuyển đổi def (mảng):
    ... trả về zip(*array)
    ...
    >>> chuyển vị([(1,2,3), (4,5,6)])
    [(1, 4), (2, 5), (3, 6)]
    >>> chuyển vị([])
    []
    

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

  • Gặp lỗi khi nhập mô-đun không còn để lại đối tượng mô-đun được khởi tạo một phần trong sys.modules. Đối tượng mô-đun chưa hoàn chỉnh bị bỏ lại sẽ đánh lừa việc nhập thêm mô-đun tương tự vào thành công, dẫn đến các lỗi khó hiểu. (Đã sửa bởi Tim Peters.)

  • None hiện là hằng số; mã liên kết một giá trị mới với tên None hiện là lỗi cú pháp. (Được đóng góp bởi Raymond Hettinger.)

Tối ưu hóa

  • Các vòng lặp bên trong để cắt danh sách và cắt bộ dữ liệu đã được tối ưu hóa và hiện chạy nhanh hơn khoảng một phần ba. Các vòng lặp bên trong dành cho từ điển cũng được tối ưu hóa, giúp tăng hiệu suất cho keys(), values(), items(), iterkeys(), itervalues()iteritems(). (Được đóng góp bởi Raymond Hettinger.)

  • Bộ máy phát triển và thu hẹp danh sách đã được tối ưu hóa về tốc độ và hiệu quả về không gian. Việc thêm và bật từ danh sách giờ đây chạy nhanh hơn nhờ đường dẫn mã hiệu quả hơn và việc sử dụng hệ thống cơ bản realloc() ít thường xuyên hơn. Việc hiểu danh sách cũng có lợi. list.extend() cũng đã được tối ưu hóa và không còn chuyển đổi đối số của nó thành danh sách tạm thời trước khi mở rộng danh sách cơ sở. (Được đóng góp bởi Raymond Hettinger.)

  • list(), tuple(), map(), filter()zip() hiện chạy nhanh hơn nhiều lần với các đối số không theo trình tự cung cấp phương thức __len__(). (Được đóng góp bởi Raymond Hettinger.)

  • Các phương thức list.__getitem__(), dict.__getitem__()dict.__contains__() hiện được triển khai dưới dạng đối tượng method_descriptor thay vì đối tượng wrapper_descriptor. Hình thức truy cập này tăng gấp đôi hiệu suất của chúng và làm cho chúng phù hợp hơn để sử dụng làm đối số cho các hàm: map(mydict.__getitem__, keylist). (Được đóng góp bởi Raymond Hettinger.)

  • Đã thêm mã hoạt động mới, LIST_APPEND, giúp đơn giản hóa mã byte được tạo để hiểu danh sách và tăng tốc chúng lên khoảng một phần ba. (Được đóng góp bởi Raymond Hettinger.)

  • Trình tối ưu hóa mã byte lỗ nhìn trộm đã được cải tiến để tạo ra mã byte ngắn hơn, nhanh hơn; đáng chú ý là mã byte kết quả dễ đọc hơn. (Được tăng cường bởi Raymond Hettinger.)

  • Việc nối chuỗi trong các câu lệnh có dạng s = s + "abc"s += "abc" hiện được thực hiện hiệu quả hơn trong một số trường hợp nhất định. Tính năng tối ưu hóa này sẽ không có trong các triển khai Python khác như Jython, vì vậy bạn không nên dựa vào nó; vẫn nên sử dụng phương pháp xâu chuỗi join() khi bạn muốn dán một số lượng lớn chuỗi lại với nhau một cách hiệu quả. (Được đóng góp bởi Armin Rigo.)

Kết quả cuối cùng của việc tối ưu hóa 2.4 là Python 2.4 chạy điểm chuẩn pystone nhanh hơn khoảng 5% so với Python 2.3 và nhanh hơn 35% so với Python 2.2. (pystone không phải là một điểm chuẩn đặc biệt tốt nhưng nó là phép đo hiệu suất của Python được sử dụng phổ biến nhất. Các ứng dụng của riêng bạn có thể cho thấy những lợi ích lớn hơn hoặc nhỏ hơn từ Python 2.4.)

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.

  • Chức năng loop() của mô-đun asyncore hiện có tham số count cho phép bạn thực hiện một số lần chuyển giới hạn qua vòng bỏ phiếu. Mặc định vẫn là lặp mãi mãi.

  • Mô-đun base64 hiện có hỗ trợ RFC 3548 hoàn chỉnh hơn cho mã hóa và giải mã Base64, Base32 và Base16, bao gồm cả cách gấp chữ hoa chữ thường và bảng chữ cái thay thế tùy chọn. (Được đóng góp bởi Barry Warsaw.)

  • Mô-đun bisect hiện có triển khai C cơ bản để cải thiện hiệu suất. (Được đóng góp bởi Dmitry Vasiliev.)

  • Bộ sưu tập CJKCodecs gồm các codec Đông Á, do Hye-Shik Chang duy trì, đã được tích hợp vào phiên bản 2.4. Các mã hóa mới là:

  • Tiếng Trung (PRC): gb2312, gbk, gb18030, big5hkscs, hz

  • Tiếng Trung (ROC): big5, cp950

  • Tiếng Nhật: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,

    iso-2022-jp-1, iso-2022-jp-2, iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004, shift-jis, shift-jisx0213, shift-jis-2004

  • Tiếng Hàn: cp949, euc-kr, johab, iso-2022-kr

  • Một số mã hóa mới khác đã được thêm vào: HP Roman8, ISO_8859-11, ISO_8859-16, PCTP-154 và TIS-620.

  • Các codec UTF-8 và UTF-16 hiện xử lý tốt hơn việc nhận một phần đầu vào. Trước đây, lớp StreamReader sẽ cố đọc thêm dữ liệu, khiến không thể tiếp tục giải mã từ luồng. Phương thức read() giờ đây sẽ trả về nhiều dữ liệu nhất có thể và các cuộc gọi trong tương lai sẽ tiếp tục giải mã ở nơi các cuộc gọi trước đó đã dừng lại. (Được thực hiện bởi Walter Dörwald.)

  • Có một mô-đun collections mới dành cho nhiều kiểu dữ liệu bộ sưu tập chuyên biệt khác nhau. Hiện tại, nó chỉ chứa một loại, deque, một hàng đợi hai đầu hỗ trợ thêm và xóa các phần tử từ một trong hai đầu một cách hiệu quả:

    >>> từ deque nhập bộ sưu tập
    >>> d = deque('ghi') # make một deque mới với ba mục
    >>> d.append('j') # add một mục mới ở bên phải
    >>> d.appendleft('f') # add một mục mới ở phía bên trái
    >>> d # show đại diện của deque
    deque(['f', 'g', 'h', 'i', 'j'])
    >>> d.pop() # return và xóa mục ngoài cùng bên phải
    'j'
    >>> d.popleft() # return và xóa mục ngoài cùng bên trái
    'f'
    >>> list(d) # list nội dung của deque
    ['g', 'h', 'tôi']
    >>> 'h' trong d # search deque
    đúng
    

    Một số mô-đun, chẳng hạn như mô-đun Queuethreading, hiện tận dụng collections.deque để cải thiện hiệu suất. (Được đóng góp bởi Raymond Hettinger.)

  • Các lớp ConfigParser đã được tăng cường một chút. Phương thức read() hiện trả về danh sách các tệp đã được phân tích cú pháp thành công và phương thức set() sẽ tăng TypeError nếu truyền một đối số value không phải là một chuỗi. (Được đóng góp bởi John Belmonte và David Goodger.)

  • Mô-đun curses hiện hỗ trợ tiện ích mở rộng use_default_colors() của ncurses. Trên nền tảng mà thiết bị đầu cuối hỗ trợ tính minh bạch, điều này cho phép sử dụng nền trong suốt. (Được đóng góp bởi Jörg Lehmann.)

  • Mô-đun difflib hiện bao gồm một lớp HtmlDiff tạo bảng HTML hiển thị so sánh cạnh nhau của hai phiên bản của một văn bản. (Đóng góp bởi Dan Gass.)

  • Gói email đã được cập nhật lên phiên bản 3.0, loại bỏ nhiều API không được dùng nữa và xóa hỗ trợ cho các phiên bản Python trước 2.3. Phiên bản 3.0 của gói sử dụng trình phân tích cú pháp gia tăng mới cho các tin nhắn MIME, có sẵn trong mô-đun email.FeedParser. Trình phân tích cú pháp mới không yêu cầu đọc toàn bộ thông báo vào bộ nhớ và không đưa ra ngoại lệ nếu thông báo không đúng định dạng; thay vào đó nó ghi lại bất kỳ vấn đề nào trong thuộc tính defect của thông báo. (Được phát triển bởi Anthony Baxter, Barry Warsaw, Thomas Wouters và những người khác.)

  • Mô-đun heapq đã được chuyển đổi thành C. Tốc độ được cải thiện gấp 10 lần giúp mô-đun này phù hợp để xử lý khối lượng dữ liệu lớn. Ngoài ra, mô-đun này còn có hai hàm mới nlargest()nsmallest() sử dụng vùng heap để tìm N giá trị lớn nhất hoặc nhỏ nhất trong tập dữ liệu mà không phải tốn chi phí sắp xếp đầy đủ. (Được đóng góp bởi Raymond Hettinger.)

  • Mô-đun httplib hiện chứa các hằng số cho mã trạng thái HTTP được xác định trong nhiều tài liệu RFC liên quan đến HTTP. Các hằng số có tên như OK, CREATED, CONTINUEMOVED_PERMANENTLY; sử dụng pydoc để có danh sách đầy đủ. (Được đóng góp bởi Andrew Eland.)

  • Mô-đun imaplib hiện hỗ trợ lệnh THREAD của IMAP (do Yves Dionne đóng góp) và các phương thức deleteacl()myrights() mới (do Arnaud Mazin đóng góp).

  • Mô-đun itertools có chức năng groupby(iterable[, *func*]). iterable là thứ có thể được lặp lại để trả về một luồng phần tử và tham số func tùy chọn là một hàm lấy một phần tử và trả về một giá trị khóa; nếu bị bỏ qua, khóa chỉ đơn giản là chính phần tử đó. groupby() sau đó nhóm các phần tử thành các chuỗi con có giá trị khóa phù hợp và trả về một chuỗi gồm 2 bộ chứa giá trị khóa và một trình vòng lặp trên chuỗi con.

    Đây là một ví dụ để làm cho điều này rõ ràng hơn. Hàm key chỉ trả về số chẵn hay số lẻ, vì vậy kết quả của groupby() là trả về các chuỗi số lẻ hoặc số chẵn liên tiếp.

    >>> nhập itertools
    >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]
    >>> đối với key_val,   trong itertools.groupby(L, lambda x: x % 2):
    ... in key_val, list(it)
    ...
    0 [2, 4, 6]
    1 [7]
    0 [8]
    1 [9, 11]
    0 [12, 14]
    >>>
    

    groupby() thường được sử dụng với đầu vào được sắp xếp. Logic của groupby() tương tự như bộ lọc uniq của Unix, giúp thuận tiện cho việc loại bỏ, đếm hoặc xác định các phần tử trùng lặp:

    >>> từ = 'abracadabra'
    >>> các chữ cái = đã sắp xếp(word) chuỗi # Turn thành danh sách các chữ cái đã được sắp xếp
    >>> chữ cái
    ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
    >>> cho k, g trong itertools.groupby(chữ cái):
    ... in k, danh sách(g)
    ...
    một ['a', 'a', 'a', 'a', 'a']
    b ['b', 'b']
    c ['c']
    d ['d']
    r ['r', 'r']
    >>> # List chữ độc đáo
    >>> [k cho k, g trong nhómby(chữ cái)]
    ['a', 'b', 'c', 'd', 'r']
    >>> số lần xuất hiện chữ cái # Count
    >>> [(k, len(list(g))) cho k, g trong nhóm(chữ cái)]
    [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
    

    (Được đóng góp bởi Hye-Shik Chang.)

  • itertools cũng có được một hàm có tên tee(iterator, N) trả về các trình vòng lặp độc lập N sao chép iterator. Nếu bỏ qua N thì mặc định là 2.

    >>> L = [1,2,3]
    >>> i1, i2 = itertools.tee(L)
    >>> i1,i2
    (<đối tượng itertools.tee tại 0x402c2080>, <đối tượng itertools.tee tại 0x402c2090>)
    >>> list(i1) # Run trình vòng lặp đầu tiên cạn kiệt
    [1, 2, 3]
    >>> list(i2) # Run trình vòng lặp thứ hai đã cạn kiệt
    [1, 2, 3]
    

    Lưu ý rằng tee() phải giữ bản sao của các giá trị được trình vòng lặp trả về; trong trường hợp xấu nhất, nó có thể cần phải giữ lại tất cả chúng. Do đó, điều này nên được sử dụng cẩn thận nếu trình vòng lặp dẫn đầu có thể chạy trước trình vòng lặp ở cuối trong một luồng đầu vào dài. Nếu khoảng cách lớn thì bạn cũng có thể sử dụng list() để thay thế. Khi các vòng lặp theo dõi chặt chẽ với nhau, tee() là lý tưởng. Các ứng dụng có thể bao gồm đánh dấu trang, cửa sổ hoặc vòng lặp tra cứu. (Được đóng góp bởi Raymond Hettinger.)

  • Một số chức năng đã được thêm vào mô-đun locale, chẳng hạn như bind_textdomain_codeset() để chỉ định một mã hóa cụ thể và một nhóm hàm l*gettext() trả về thông báo trong mã hóa đã chọn. (Đóng góp bởi Gustavo Niemeyer.)

  • Một số đối số từ khóa đã được thêm vào hàm basicConfig() của gói logging để đơn giản hóa cấu hình nhật ký. Hành vi mặc định là ghi thông báo vào lỗi tiêu chuẩn, nhưng có thể chỉ định nhiều đối số từ khóa khác nhau để ghi vào một tệp cụ thể, thay đổi định dạng ghi nhật ký hoặc đặt mức ghi nhật ký. Ví dụ:

    nhập nhật 
    logging.basicConfig(filename='/var/log/application.log',
        cấp độ = 0, # Log tất cả tin nhắn
        format='%(levelname):%(process):%(thread):%(message)')
    

    Các bổ sung khác cho gói logging bao gồm phương thức tiện lợi log(level, msg), cũng như lớp TimedRotatingFileHandler xoay các tệp nhật ký của nó theo một khoảng thời gian định sẵn. Mô-đun này đã có RotatingFileHandler, chức năng này sẽ xoay nhật ký khi tệp vượt quá một kích thước nhất định. Cả hai lớp đều bắt nguồn từ lớp BaseRotatingHandler mới có thể được sử dụng để triển khai các trình xử lý xoay khác.

    (Những thay đổi được thực hiện bởi Vinay Sajip.)

  • Mô-đun marshal hiện chia sẻ các chuỗi nội bộ khi giải nén cấu trúc dữ liệu. Điều này có thể thu nhỏ kích thước của một số chuỗi dưa nhất định, nhưng tác dụng chính là làm cho các tệp .pyc nhỏ hơn đáng kể. (Được đóng góp bởi Martin von Löwis.)

  • Lớp NNTP của mô-đun nntplib đã nhận được các phương thức description()descriptions() để truy xuất các mô tả nhóm tin cho một nhóm hoặc cho một loạt các nhóm. (Được đóng góp bởi Jürgen A. Erhard.)

  • Hai chức năng mới đã được thêm vào mô-đun operator, attrgetter(attr)itemgetter(index). Cả hai hàm đều trả về các lệnh gọi có một đối số duy nhất và trả về thuộc tính hoặc mục tương ứng; những lệnh gọi này tạo ra trình trích xuất dữ liệu tuyệt vời khi được sử dụng với map() hoặc sorted(). Ví dụ:

    >>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
    >>> bản đồ(operator.itemgetter(0), L)
    ['c', 'd', 'a', 'b']
    >>> bản đồ(operator.itemgetter(1), L)
    [2, 1, 4, 3]
    >>> được sắp xếp(L, key=operator.itemgetter(1)) danh sách # Sort theo mục tuple thứ hai
    [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
    

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

  • Mô-đun optparse đã được cập nhật theo nhiều cách khác nhau. Mô-đun hiện chuyển các thông báo của nó qua gettext.gettext(), giúp có thể quốc tế hóa các thông báo lỗi và trợ giúp của Optik. Thông báo trợ giúp cho các tùy chọn hiện có thể bao gồm chuỗi '%default', chuỗi này sẽ được thay thế bằng giá trị mặc định của tùy chọn. (Được đóng góp bởi Greg Ward.)

  • Kế hoạch dài hạn là không dùng mô-đun rfc822 trong một số bản phát hành Python trong tương lai để chuyển sang gói email. Vì mục đích này, chức năng email.Utils.formatdate đã được thay đổi để có thể sử dụng nó thay thế cho rfc822.formatdate(). Bạn có thể muốn viết mã xử lý e-mail mới với ý tưởng này. (Thay đổi được thực hiện bởi Anthony Baxter.)

  • Một hàm urandom(n) mới đã được thêm vào mô-đun os, trả về một chuỗi chứa n byte dữ liệu ngẫu nhiên. Chức năng này cung cấp quyền truy cập vào các nguồn ngẫu nhiên dành riêng cho nền tảng, chẳng hạn như /dev/urandom trên Linux hoặc Windows CryptoAPI. (Được đóng góp bởi Trevor Perrin.)

  • Một chức năng mới khác: os.path.lexists(path) trả về true nếu tệp được chỉ định bởi path tồn tại, cho dù đó có phải là liên kết tượng trưng hay không. Điều này khác với hàm os.path.exists(path) hiện có, hàm này trả về sai nếu path là một liên kết tượng trưng trỏ đến đích không tồn tại. (Được đóng góp bởi Beni Cherniavsky.)

  • Một chức năng getsid() mới đã được thêm vào mô-đun posix làm nền tảng cho mô-đun os. (Đóng góp bởi J. Raynor.)

  • Mô-đun poplib hiện hỗ trợ POP trên SSL. (Được đóng góp bởi Hector Urtubia.)

  • Mô-đun profile hiện có thể cấu hình các chức năng mở rộng C. (Được đóng góp bởi Nick Bastin.)

  • Mô-đun random có một phương thức mới gọi là getrandbits(N) trả về một số nguyên dài N có độ dài bit. Phương pháp randrange() hiện tại sử dụng getrandbits() khi thích hợp, giúp việc tạo số ngẫu nhiên lớn tùy ý hiệu quả hơn. (Được đóng góp bởi Raymond Hettinger.)

  • Ngôn ngữ biểu thức chính quy được mô-đun re chấp nhận đã được mở rộng với các biểu thức điều kiện đơn giản, được viết là (?(group)A|B). group là ID nhóm số hoặc tên nhóm được xác định bằng (?P<group>...) trước đó trong biểu thức. Nếu nhóm được chỉ định khớp, mẫu biểu thức chính quy A sẽ được kiểm tra dựa trên chuỗi; nếu nhóm không khớp, mẫu B sẽ được sử dụng thay thế. (Đóng góp bởi Gustavo Niemeyer.)

  • Mô-đun re cũng không còn đệ quy nữa nhờ khối lượng công việc khổng lồ của Gustavo Niemeyer. Trong công cụ biểu thức chính quy đệ quy, một số mẫu nhất định dẫn đến việc tiêu tốn một lượng lớn không gian ngăn xếp C và có thể làm tràn ngăn xếp. Ví dụ: nếu bạn so khớp chuỗi 30000 byte gồm các ký tự a với biểu thức (a|b)+, thì một khung ngăn xếp sẽ được tiêu thụ cho mỗi ký tự. Python 2.3 đã cố kiểm tra lỗi tràn ngăn xếp và đưa ra ngoại lệ RuntimeError, nhưng một số mẫu nhất định có thể bỏ qua việc kiểm tra và nếu bạn không may mắn thì Python có thể phân tách. Công cụ biểu thức chính quy của Python 2.4 có thể khớp với mẫu này mà không gặp vấn đề gì.

  • Mô-đun signal hiện thực hiện kiểm tra lỗi chặt chẽ hơn trên các tham số của chức năng signal.signal(). Ví dụ: bạn không thể đặt trình xử lý tín hiệu SIGKILL; các phiên bản trước của Python sẽ lặng lẽ chấp nhận điều này, nhưng 2.4 sẽ đưa ra ngoại lệ RuntimeError.

  • Hai chức năng mới đã được thêm vào mô-đun socket. socketpair() trả về một cặp ổ cắm được kết nối và getservbyport(port) tra cứu tên dịch vụ cho một số cổng nhất định. (Được đóng góp bởi Dave Cole và Barry Warsaw.)

  • Chức năng sys.exitfunc() không còn được dùng nữa. Mã phải sử dụng mô-đun atexit hiện có để xử lý chính xác việc gọi nhiều hàm thoát. Cuối cùng, sys.exitfunc() sẽ trở thành một giao diện nội bộ thuần túy, chỉ được truy cập bởi atexit.

  • Mô-đun tarfile hiện tạo các tệp tar có định dạng GNU theo mặc định. (Được đóng góp bởi Lars Gustäbel.)

  • Mô-đun threading hiện có một cách đơn giản để hỗ trợ dữ liệu luồng cục bộ. Mô-đun này chứa một lớp local có các giá trị thuộc tính cục bộ cho các luồng khác nhau.

    nhập luồng
    
    dữ liệu = threading.local()
    dữ liệu.số = 42
    data.url = ('www.python.org', 80)
    

    Các luồng khác có thể gán và truy xuất các giá trị riêng của chúng cho thuộc tính numberurl. Bạn có thể phân lớp local để khởi tạo các thuộc tính hoặc thêm các phương thức. (Được đóng góp bởi Jim Fulton.)

  • Mô-đun timeit hiện tự động vô hiệu hóa việc thu thập rác định kỳ trong vòng lặp thời gian. Sự thay đổi này làm cho thời gian liên tiếp dễ so sánh hơn. (Được đóng góp bởi Raymond Hettinger.)

  • Mô-đun weakref hiện hỗ trợ nhiều đối tượng hơn bao gồm các hàm Python, phiên bản lớp, bộ, tập hợp cố định, deques, mảng, tệp, ổ cắm và các đối tượng mẫu biểu thức chính quy. (Được đóng góp bởi Raymond Hettinger.)

  • Mô-đun xmlrpclib hiện hỗ trợ tiện ích mở rộng nhiều cuộc gọi để truyền nhiều cuộc gọi XML-RPC trong một thao tác HTTP duy nhất. (Được đóng góp bởi Brian Quinlan.)

  • Các mô-đun mpz, rotorxreadlines đã bị xóa.

cookielib

Thư viện cookielib hỗ trợ xử lý phía máy khách đối với cookie HTTP, phản ánh hỗ trợ cookie phía máy chủ của mô-đun Cookie. Bánh quy được đựng trong lọ đựng bánh quy; thư viện lưu trữ một cách minh bạch các cookie do máy chủ web cung cấp trong lọ cookie và tìm nạp cookie từ lọ khi kết nối với máy chủ. Giống như trong trình duyệt web, các đối tượng chính sách kiểm soát xem cookie có được chấp nhận hay không.

Để lưu trữ cookie qua các phiên, hai triển khai lọ cookie được cung cấp: một lưu trữ cookie ở định dạng Netscape để các ứng dụng có thể sử dụng tệp cookie Mozilla hoặc Lynx và một lưu trữ cookie ở cùng định dạng với thư viện Perl libwww.

urllib2 đã được thay đổi để tương tác với cookielib: HTTPCookieProcessor quản lý một lọ cookie được sử dụng khi truy cập URL.

Mô-đun này được đóng góp bởi John J. Lee.

doc nhất

Mô-đun doctest đã được tái cấu trúc đáng kể nhờ Edward Loper và Tim Peters. Việc kiểm tra vẫn có thể đơn giản như chạy doctest.testmod(), nhưng việc tái cấu trúc cho phép tùy chỉnh hoạt động của mô-đun theo nhiều cách khác nhau

Lớp DocTestFinder mới trích xuất các bài kiểm tra từ chuỗi tài liệu của một đối tượng nhất định:

định nghĩa f (x, y):
    """>>> f(2,2)
4
>>>f(3,2)
6
    """
    trả về x*y

công cụ tìm = doctest.DocTestFinder()

danh sách # Get của các phiên bản DocTest
kiểm tra = finder.find(f)

Sau đó, lớp DocTestRunner mới sẽ chạy các bài kiểm tra riêng lẻ và có thể tạo ra bản tóm tắt kết quả:

Á hậu = doctest.DocTestRunner()
cho t trong các bài kiểm tra:
    đã thử, thất bại = Runner.run(t)

á quân.tóm tắt(dài=1)

Ví dụ trên tạo ra kết quả đầu ra sau:

1 mục đã vượt qua tất cả các bài kiểm tra:
   2 bài kiểm tra trong f
2 bài kiểm tra trong 1 mục.
2 đạt  0 thất bại.
Thử nghiệm đã trôi qua.

DocTestRunner sử dụng một phiên bản của lớp OutputChecker để so sánh kết quả đầu ra dự kiến với đầu ra thực tế. Lớp này có một số cờ khác nhau để tùy chỉnh hành vi của nó; những người dùng đầy tham vọng cũng có thể viết một lớp con hoàn toàn mới của OutputChecker.

Trình kiểm tra đầu ra mặc định cung cấp một số tính năng tiện dụng. Ví dụ: với cờ tùy chọn doctest.ELLIPSIS, dấu chấm lửng (...) trong đầu ra dự kiến khớp với bất kỳ chuỗi con nào, giúp dễ dàng điều chỉnh các đầu ra khác nhau theo những cách nhỏ hơn:

định nghĩa o (n):
    """>>> o(1)
<__main__.C phiên bản tại 0x...>
>>>
"""

Một chuỗi đặc biệt khác, <BLANKLINE>, khớp với một dòng trống:

định nghĩa p (n):
    """>>> p(1)
<BLANKLINE>
>>>
"""

Một khả năng mới khác là tạo ra màn hình hiển thị đầu ra theo kiểu khác nhau bằng cách chỉ định các cờ tùy chọn doctest.REPORT_UDIFF (khác biệt thống nhất), doctest.REPORT_CDIFF (khác biệt ngữ cảnh) hoặc doctest.REPORT_NDIFF (kiểu delta). Ví dụ:

def g (n):
    """>>>g(4)
ở đây

một
dài dòng
>>>"""
    L = 'đây là danh sách các từ khá dài'.split()
    cho từ trong L[:n]:
        in chữ

Chạy thử nghiệm hàm trên với doctest.REPORT_UDIFF được chỉ định, bạn sẽ nhận được kết quả đầu ra sau:

*************************************************************************
Tệp "t.py", dòng 15, trong g
Ví dụ không thành công:
    g(4)
Sự khác biệt (khác biệt thống nhất với -expected +actual):
    @@ -2,3 +2,3 @@
     là
     một
    -dài
    +đúng hơn
*************************************************************************

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

Một số thay đổi đối với quy trình xây dựng của Python và đối với C API là:

  • Ba macro tiện lợi mới đã được thêm vào cho các giá trị trả về chung từ các hàm mở rộng: Py_RETURN_NONE, Py_RETURN_TRUEPy_RETURN_FALSE. (Được đóng góp bởi Brett Cannon.)

  • Một macro mới khác, Py_CLEAR, giảm số lượng tham chiếu của obj và đặt obj thành con trỏ null. (Được đóng góp bởi Jim Fulton.)

  • Một hàm mới, PyTuple_Pack(N, obj1, obj2, ..., objN), xây dựng các bộ dữ liệu từ danh sách đối số có độ dài thay đổi của các đối tượng Python. (Được đóng góp bởi Raymond Hettinger.)

  • Một chức năng mới, PyDict_Contains(d, k), thực hiện tra cứu từ điển nhanh chóng mà không che giấu các ngoại lệ được đưa ra trong quá trình tra cứu. (Được đóng góp bởi Raymond Hettinger.)

  • Macro Py_IS_NAN(X) trả về 1 nếu đối số float hoặc double X của nó là NaN. (Được đóng góp bởi Tim Peters.)

  • Mã C có thể tránh việc khóa không cần thiết bằng cách sử dụng hàm PyEval_ThreadsInitialized() mới để biết liệu có bất kỳ thao tác luồng nào đã được thực hiện hay không. Nếu hàm này trả về sai thì không cần thực hiện thao tác khóa nào. (Được đóng góp bởi Nick Coghlan.)

  • Một hàm mới, PyArg_VaParseTupleAndKeywords(), giống như PyArg_ParseTupleAndKeywords() nhưng lấy va_list thay vì một số đối số. (Được đóng góp bởi Greg Chapman.)

  • Cờ phương thức mới, METH_COEXIST, cho phép một hàm được xác định trong các vị trí cùng tồn tại với PyCFunction có cùng tên. Điều này có thể giảm một nửa thời gian truy cập cho một phương thức như set.__contains__(). (Được đóng góp bởi Raymond Hettinger.)

  • Giờ đây, Python có thể được xây dựng với cấu hình bổ sung cho chính trình thông dịch, nhằm mục đích hỗ trợ những người phát triển lõi Python. Việc cung cấp --enable-profiling cho tập lệnh configure sẽ cho phép bạn lập hồ sơ trình thông dịch với gprof và việc cung cấp khóa chuyển --with-tsc cho phép lập hồ sơ bằng cách sử dụng thanh ghi Bộ đếm thời gian của Pentium. Lưu ý rằng công tắc --with-tsc bị đặt tên hơi sai vì tính năng lập hồ sơ cũng hoạt động trên nền tảng PowerPC, mặc dù kiến ​​trúc bộ xử lý đó không gọi thanh ghi đó là "thanh ghi TSC". (Được đóng góp bởi Jeremy Hylton.)

  • Loại tracebackobject đã được đổi tên thành PyTracebackObject.

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

  • Cổng Windows hiện được xây dựng theo MSVC++ 7.1 cũng như phiên bản 6. (Được đóng góp bởi Martin von Löwis.)

Chuyển sang Python 2.4

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:

  • Dịch chuyển trái và hằng số thập lục phân/bát phân quá lớn không còn kích hoạt FutureWarning và trả về giá trị giới hạn ở 32 hoặc 64 bit; thay vào đó họ trả về một số nguyên dài.

  • Các phép toán số nguyên sẽ không còn kích hoạt OverflowWarning nữa. Cảnh báo OverflowWarning sẽ biến mất trong Python 2.5.

  • Hàm tích hợp zip()itertools.izip() hiện trả về một danh sách trống thay vì đưa ra ngoại lệ TypeError nếu được gọi mà không có đối số.

  • Bạn không thể so sánh các phiên bản datedatetime do mô-đun datetime cung cấp nữa. Hai phiên bản của các lớp khác nhau bây giờ sẽ luôn không bằng nhau và các so sánh tương đối (<, >) sẽ tạo ra TypeError.

  • dircache.listdir() hiện chuyển ngoại lệ cho người gọi thay vì trả về danh sách trống.

  • LexicalHandler.startDTD() được sử dụng để nhận ID công khai và ID hệ thống không đúng thứ tự. Điều này đã được sửa chữa; các ứng dụng sai thứ tự cần phải được sửa chữa.

  • fcntl.ioctl() hiện cảnh báo nếu đối số mutate bị bỏ qua và có liên quan.

  • Mô-đun tarfile hiện tạo các tệp tar có định dạng GNU theo mặc định.

  • Gặp lỗi khi nhập mô-đun không còn để lại đối tượng mô-đun được khởi tạo một phần trong sys.modules.

  • None hiện là hằng số; mã liên kết một giá trị mới với tên None hiện là lỗi cú pháp.

  • Hàm signals.signal() hiện đưa ra ngoại lệ RuntimeError đối với một số giá trị không hợp lệ; trước đây những lỗi này sẽ trôi qua một cách âm thầm. Ví dụ: bạn không còn có thể đặt trình xử lý trên tín hiệu SIGKILL nữa.

Lời cảm ơn

Tác giả xin cảm ơn những người sau đây đã đưa ra những gợi ý, chỉnh sửa và hỗ trợ cho các bản thảo khác nhau của bài viết này: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, Sadruddin Rejeb.