2011-07-04 31 views
14

Tò mò:Thời điểm sử dụng == và thời điểm sử dụng?

>>> a = 123 
>>> b = 123 
>>> a is b 
True 
>>> a = 123. 
>>> b = 123. 
>>> a is b 
False 

vẻ a is b được nhiều hơn hoặc ít hơn định nghĩa là id(a) == id(b). Nó rất dễ dàng để làm cho lỗi theo cách này:

basename, ext = os.path.splitext(fname) 
if ext is '.mp3': 
    # do something 
else: 
    # do something else 

Một số tên bất ngờ kết thúc trong khối khác. Việc sửa chữa là đơn giản, chúng ta nên sử dụng ext == '.mp3' thay vào đó, nhưng dù sao if ext is '.mp3' trên bề mặt có vẻ giống như một cách tốt đẹp pythonic để viết này và nó dễ đọc hơn cách "đúng".

Vì chuỗi là bất biến, các chi tiết kỹ thuật về lý do sai? Khi nào thì kiểm tra danh tính tốt hơn và khi nào thì kiểm tra bình đẳng tốt hơn?

+2

* related: * [Python '==' vs 'là' so sánh các chuỗi, 'là' không thành công đôi khi, tại sao?] (Http://stackoverflow.com/questions/1504717/python-vs-is -comparing-strings-is-fail-sometimes-why) –

+0

có thể trùng lặp của [Khi nào toán tử \ '== \' không tương đương với toán tử \ 'is \'? (Python)] (http://stackoverflow.com/questions/3647692/when-is-the-operator-not-equivalent-to-the-is-operator-python) – user

+0

liên quan: http://stackoverflow.com/ a) 2577589/674039 – wim

Trả lời

5

Theo như tôi có thể biết, is kiểm tra tương đương danh tính đối tượng. Vì không có chuỗi bắt buộc "interning", hai chuỗi chỉ xảy ra để có cùng các ký tự trong chuỗi, thông thường, không phải là cùng một đối tượng chuỗi.

Khi bạn trích xuất chuỗi con từ chuỗi (hoặc, thực sự, bất kỳ chuỗi nào từ chuỗi), bạn sẽ kết thúc với hai đối tượng khác nhau, chứa cùng một giá trị.

Vì vậy, hãy sử dụng is khi nào và chỉ khi bạn đang so sánh danh tính đối tượng. Sử dụng == khi so sánh các giá trị.

+3

Thực tế, có _is_ chuỗi thực tập. Nó sẽ không xảy ra cho các chuỗi được tạo động. – katrielalex

+0

@katrielalex có một nội trang 'intern()' cho phép bạn * rõ ràng * các chuỗi được tạo theo kiểu động; nó không tự xảy ra. – Duncan

+1

@ katriealex: Tôi nghĩ rằng tôi thực sự có nghĩa là "tự động và bắt buộc chuỗi-interning" (có, tôi tin rằng, một số ngôn ngữ mà làm điều đó). – Vatine

20

Về cơ bản chúng khác nhau.

  1. == so sánh bằng cách gọi phương pháp __eq__
  2. is trả về true khi và chỉ khi hai tham chiếu đến cùng đối tượng

Vì vậy, trong so sánh với tiếng nói Java:

  1. is giống với == cho các đối tượng
  2. == cũng giống như equals cho các đối tượng
6

quy tắc đơn giản để xác định nếu để sử dụng là hay == bằng Python

Dưới đây là một nguyên tắc đơn giản (trừ khi bạn muốn đi đến lý thuyết bằng Python thông dịch viên hoặc xây dựng các khung làm những điều thú vị với các đối tượng Python):

Chỉ sử dụng cho Không so sánh.

if foo is None 

Nếu không, hãy sử dụng ==.

if x == 3 

Sau đó, bạn đang ở bên an toàn. Lý do cho điều này đã được giải thích trong các bình luận ở trên. Không sử dụng là nếu bạn không chắc chắn 100% lý do tại sao để làm điều đó.

+1

Cách Python là mã có thể đọc được, có nghĩa là sử dụng '== 'miễn là đó là ý của bạn (hầu như luôn luôn). 'là None'' nếu x: '' nếu không x: 'là quy ước Python để kiểm tra' None True False' tương ứng. Việc sử dụng thực sự 'is' xuất hiện khi bạn kiểm tra cấu trúc dữ liệu phức tạp, ví dụ: 'khẳng định không [l cho l trong danh sách của tôi nếu l là danh sách của tôi]' một kiểm tra đơn giản đối với các chu kỳ trong cấu trúc dữ liệu (đồng bằng). –

+0

điều gì về các loại? 'type (" foo ") là str' có lẽ là ok –

0

Sẽ rất hữu ích khi xác định một lớp như thế này sẽ được sử dụng làm giá trị mặc định cho các hằng số được sử dụng trong API của bạn.Trong trường hợp này, sẽ chính xác hơn khi sử dụng là toán tử ==.

class Sentinel(object): 
    """A constant object that does not change even when copied.""" 
    def __deepcopy__(self, memo): 
     # Always return the same object because this is essentially a constant. 
     return self 

    def __copy__(self): 
     # called via copy.copy(x) 
     return self 
Các vấn đề liên quan