__ CMP __ trăn là gì?

Bạn cũng có thể muốn đọc chương về , trong đó có nhiều cải tiến khác mà bạn có thể áp dụng cho mã của mình

Chạy bằng Python 2. 7

Bước đầu tiên trong quy trình là chạy mã của bạn bằng Python 2. 6 hoặc 2. 7. Việc bạn sử dụng phiên bản nào ở đây không quan trọng lắm, nhưng rõ ràng phiên bản Python 2 cuối cùng có ý nghĩa nhất, vì vậy nếu bạn có thể sử dụng Python 2. 7, làm như vậy

Hầu hết mã sẽ chạy trực tiếp mà không cần sửa đổi, nhưng có một số điều thay đổi so với Python 2. 5 đến 2. 6. Trong Python 2. 6 aswith là từ khóa, vì vậy nếu bạn sử dụng chúng làm biến . Đơn giản nhất là thêm dấu gạch dưới vào cuối các biến.

>>> with_ = True >>> as_ = False

Bạn cũng cần loại bỏ các ngoại lệ chuỗi. Việc sử dụng các chuỗi cho các ngoại lệ đã được khuyến nghị trong một thời gian rất dài, chủ yếu là do chúng rất không linh hoạt, chẳng hạn như bạn không thể phân lớp chúng

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong!

Trong Python 3 ngoại lệ chuỗi đã hoàn toàn biến mất. Bằng Python 2. 6 bạn không thể nuôi chúng, mặc dù bạn vẫn có thể bắt chúng để tương thích ngược. Trong bất kỳ trường hợp nào, bạn nên xóa tất cả việc sử dụng ngoại lệ chuỗi trong mã của mình và làm cho mã đó chạy trong Python 2. 6 trước khi làm bất cứ điều gì khác

>>> raise Exception("Something went wrong!") Traceback (most recent call last): ... Exception: Something went wrong!

Bước tiếp theo là chạy mã của bạn trong Python 2. 6 hoặc Python 2. 7 với tùy chọn -3 . Thao tác này sẽ cảnh báo về những thứ không được hỗ trợ trong Python 3 và những thứ 2to3 sẽ không chuyển đổi. Đó chủ yếu là những cách thực hiện những việc đã bị phản đối từ lâu và có những cách thay thế mới hơn để thực hiện hoặc các mô-đun bị xóa khỏi thư viện tiêu chuẩn. Ví dụ: hỗ trợ cho Mac OS cổ điển đã bị xóa trong Python 3, hiện chỉ hỗ trợ OS X và vì lý do đó, các mô-đun hỗ trợ những thứ cụ thể về Mac OS cổ điển đã bị xóa.

Bạn sẽ nhận được cảnh báo về nhiều thay đổi được liệt kê bên dưới (nhưng không phải tất cả), cũng như đối với một số việc sắp xếp lại thư viện. Các thay đổi sắp xếp lại thư viện rất đơn giản và không cần giải thích, các cảnh báo sẽ cho bạn biết tên mới của mô-đun

Sử dụng // thay vì / khi chia các số nguyên

Trong Python 2 chia hai số nguyên trả về một số nguyên. Điều đó có nghĩa là năm chia hai sẽ trả lại hai

>>> 5/2 2

Tuy nhiên, trong Python 3, nó trả về hai rưỡi

>>> 5/2 2.5

Ngày nay, nhiều người sử dụng toán tử chia trong Python 2 dựa vào phép chia số nguyên để luôn trả về số nguyên. Nhưng việc chuyển đổi tự động với 2to3 sẽ không biết toán hạng là loại gì và do đó không biết toán tử chia có chia hết số nguyên hay không. Do đó, nó không thể thực hiện bất kỳ chuyển đổi nào ở đây. Điều này có nghĩa là nếu bạn đang sử dụng phép chia số nguyên cũ, thì mã của bạn có thể bị lỗi trong Python 3.

Vì thay đổi này đã được lên kế hoạch từ Python 2. 2, nó và tất cả các phiên bản sau này bao gồm một toán tử mới, được gọi là phép chia tầng, được viết bằng hai dấu gạch chéo. Nó luôn trả về toàn bộ số nguyên, ngay cả với số float. Bất kỳ vị trí nào trong mã của bạn mà bạn thực sự muốn phép chia tầng trả về số nguyên, bạn nên thay đổi toán tử chia thành toán tử chia sàn

>>> 5//2 2 >>> 5.0//2.0 2.0

Thường thì hành vi chia số nguyên trong Python 2 là không mong muốn. Cách phổ biến nhất để giải quyết vấn đề đó là chuyển đổi một trong các số nguyên thành số float hoặc thêm dấu phẩy thập phân vào một trong các số

>>> 5/2.0 2.5 >>> a = 5 >>> b = 2 >>> float(a)/b 2.5

Tuy nhiên, có một cách gọn gàng hơn để thực hiện việc này, đó là kích hoạt hành vi Python 3. Điều này được thực hiện thông qua nhập __future__ cũng có sẵn kể từ Python 2. 2.

>>> from __future__ import division >>> 5/2 2.5

Mặc dù việc chuyển đổi một trong các toán hạng thành số float trước khi chia sẽ hoạt động tốt nhưng điều này là không cần thiết trong Python 3 và bằng cách sử dụng __future__ , bạn sẽ nhập được .

Chạy Python 2. 6 với tùy chọn -3 sẽ cảnh báo bạn nếu bạn sử dụng phép chia số nguyên cũ.

Sử dụng các lớp học kiểu mới

Trong Python 2 có hai loại lớp, “kiểu cũ” và “mới”. Các lớp "kiểu cũ" đã bị xóa trong Python 3, vì vậy, tất cả các lớp hiện được phân lớp từ đối tượng , ngay cả khi chúng không làm như vậy một cách rõ ràng.

Có nhiều sự khác biệt giữa các lớp mới và cũ, nhưng một vài trong số chúng sẽ gây ra cho bạn bất kỳ vấn đề nào với Python 3. Nếu bạn sử dụng nhiều kế thừa, có thể bạn sẽ gặp sự cố do các thứ tự giải quyết phương thức khác nhau

Nếu bạn sử dụng đa kế thừa, do đó, bạn nên chuyển sang sử dụng các lớp kiểu mới trước khi thêm hỗ trợ Python 3. Điều này được thực hiện bằng cách đảm bảo tất cả các lớp con của đối tượng từ đối tượng , và bạn có thể sẽ phải thay đổi thứ tự liệt kê các siêu lớp trong định nghĩa lớp.

Tách dữ liệu nhị phân và chuỗi

Trong Python 2, bạn sử dụng các đối tượng str để chứa dữ liệu nhị phân và văn bản ASCII, trong khi dữ liệu văn bản cần nhiều ký tự hơn những gì có sẵn . Trong Python 3, thay vì các đối tượng unicode objects. In Python 3, instead of strunicode , bạn sử dụng < . Loại bytes objects for binary data and str objects for all kinds of text data, Unicode or not. The str trong Python 3 ít nhiều giống với unicode type in Python 2 and the bytes type is quite similar to Python 2’s str type, even though there are significant differences.

Bước đầu tiên để chuẩn bị cho điều này là đảm bảo rằng bạn không sử dụng cùng một tên biến cho cả dữ liệu nhị phân và dữ liệu văn bản. Trong Python 2, điều này sẽ không gây nhiều rắc rối cho bạn, nhưng trong Python 3 thì có, vì vậy hãy cố gắng tách biệt dữ liệu nhị phân và văn bản càng nhiều càng tốt

Trong Python 2, không''b' file mode flags changes how newlines are treated on some platforms, for example Windows. But the flag makes no difference on Unix, so many programs that are developed for Unix tend to ignore that flag and open binary files in text mode. However, in Python 3 the flags also determine if you get byte hay unicode objects as results when you read from the file. So make sure you really use the text and binary flags when you open a file. Although the text flag is default, add it anyway, as you then show that the text mode is intentional and not just because you forgot to add the flag.

Chạy Python 2. 6 có tùy chọn -3 sẽ không cảnh báo về sự cố này vì đơn giản là không có cách nào để Python 2 biết dữ liệu là văn bản hay dữ liệu nhị phân.

Khi sắp xếp, hãy sử dụng phím key thay vì cmp

Trong Python 2, các phương pháp sắp xếp nhận một tham số cmp . Tham số này phải là một hàm trả về -1, 0 hoặc 1 khi so sánh hai giá trị.

________số 8_______

Vì Python 2. 4 . sort() cũng như hàm sorted() mới (xem ) take a key parameter which should be a function that returns a sorting key.

>>> def keyfunction(item): .. """Key for comparison that ignores the first letter""" .. return item[1:] >>> names = ['Adam', 'Donald', 'John'] >>> names.sort(key=keyfunction) >>> names ['Adam', 'John', 'Donald']

Điều này dễ sử dụng hơn và chạy nhanh hơn. Khi sử dụng tham số cmp , quá trình sắp xếp sẽ so sánh các cặp giá trị, vì vậy hàm so sánh được gọi nhiều lần cho mỗi mục. Tập dữ liệu càng lớn, hàm so sánh được gọi cho mỗi mục càng nhiều lần. Với hàm key , việc sắp xếp sẽ giữ giá trị khóa cho mỗi mục và so sánh các giá trị đó, vì vậy hàm key chỉ được gọi một lần cho mỗi mục. Điều này dẫn đến việc sắp xếp nhanh hơn nhiều đối với các tập dữ liệu lớn.

Hàm key thường đơn giản đến mức bạn có thể thay thế bằng lambda.

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 0

Trăn 2. 4 cũng giới thiệu tham số reverse .

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 1

Có một trường hợp sử dụng khóa key ít rõ ràng hơn so với sử dụng cmp and that’s when you need to sort on several values. Let’s say we want the result to be sorted with the longest names first and names of the same length should be sorted alphabetically. Doing this with a key không rõ ràng ngay lập tức, nhưng giải pháp thường là sắp xếp hai lần, sắp xếp ít quan trọng nhất trước.

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 2

Điều này hiệu quả vì kể từ Python 2. 3 thuật toán sắp xếp timsort được sử dụng. Đó là một thuật toán ổn định, nghĩa là nếu hai mục được sắp xếp bằng nhau thì thứ tự của các mục đó sẽ được giữ nguyên

Bạn cũng có thể tạo một hàm khóa trả về một giá trị kết hợp hai khóa và sắp xếp trong một lần. Điều này đáng ngạc nhiên là không phải lúc nào cũng nhanh hơn, bạn sẽ phải kiểm tra giải pháp nào nhanh hơn trong trường hợp của mình, nó phụ thuộc vào cả dữ liệu và chức năng chính

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 3

Thông số key đã được giới thiệu trong Python 2. 4, vì vậy nếu bạn cần hỗ trợ Python 2. 3 bạn không thể sử dụng nó. Nếu bạn cần thực hiện nhiều thao tác sắp xếp bằng hàm key, thì tốt nhất bạn nên triển khai một hàm sorted() đơn giản cho Python 2. 3 và sử dụng nó một cách có điều kiện thay vì sorted() dựng sẵn bằng Python 2. 4 trở lên.

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 4

Trăn 2. 4 hiện đã hơn 5 năm tuổi, vì vậy, rất có thể bạn sẽ không cần hỗ trợ Python 2. 3

Cảnh báo

Chạy Python với tùy chọn -3 sẽ chỉ cảnh báo bạn nếu bạn sử dụng cmp parameter explicitly:

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 5

Nhưng nó sẽ không cảnh báo nếu bạn sử dụng nó như thế này

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 6

Vì vậy, cú pháp này có thể trượt qua. Trong những trường hợp này, bạn gặp phải TypeError. phải sử dụng từ khóa đối số cho . key function when running the code under Python 3.

Trong Python 2. 7 và Trăn 3. 2 trở lên, có một hàm sẽ chuyển đổi hàm so sánh thành hàm chính thông qua lớp trình bao bọc. Nó rất thông minh, nhưng sẽ làm cho chức năng so sánh thậm chí còn chậm hơn, vì vậy chỉ sử dụng nó như là phương sách cuối cùng

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 7

Sử dụng các toán tử so sánh phong phú

Trong Python 2, cách phổ biến nhất để hỗ trợ so sánh và sắp xếp các đối tượng của bạn là triển khai một phương thức __cmp__() . . cmp() function, like this class that will sort according to lastname:

>>> raise "Something went wrong!" Traceback (most recent call last): ... Something went wrong! 8

Tuy nhiên, bạn có thể có các đối tượng, chẳng hạn như màu, không “nhỏ hơn” cũng không “lớn hơn”, nhưng vẫn có thể “bằng” hoặc “không bằng”, do đó, vì Python 2. 1 cũng đã hỗ trợ cho các phương thức so sánh phong phú trong đó mỗi phương thức tương ứng với một toán tử so sánh. Họ là __lt__ cho =.

Việc có cả phương pháp so sánh phong phú và phương pháp __cmp__() vi phạm nguyên tắc chỉ nên có một cách rõ ràng để thực hiện điều đó, . Do đó, đối với Python 3, bạn phải triển khai tất cả các toán tử so sánh phong phú nếu bạn muốn các đối tượng của mình có thể so sánh được. Bạn không cần phải làm điều này trước khi hỗ trợ Python 3 nhưng làm như vậy sẽ giúp trải nghiệm mượt mà hơn một chút. __cmp__() has been removed. For Python 3 you therefore must implement all of the rich comparison operators if you want your objects to be comparable. You don’t have to do this before supporting Python 3 but doing so makes the experience a bit smoother.

Tương đối khó

Việc tạo các phương thức so sánh có thể khá phức tạp, vì bạn cũng cần xử lý việc so sánh các loại khác nhau. Các phương thức so sánh phải trả về hằng số NotImplemented nếu nó không biết cách so sánh với đối tượng khác. Trả về NotImplemented hoạt động như một cờ cho phép so sánh Python khiến Python thử so sánh ngược lại. Vì vậy, nếu phương thức __lt__() của bạn trả về NotImplemented thì Python sẽ cố gắng . __gt__() method instead.

Chú ý

Điều này có nghĩa là bạn không bao giờ được gọi toán tử so sánh các đối tượng khác trong các phương thức so sánh phong phú của mình. Bạn sẽ tìm thấy một số ví dụ về trình trợ giúp so sánh phong phú sẽ chuyển đổi cuộc gọi lớn hơn như self. __gt__(other) vào return other

Chủ đề