2011-11-18 35 views
8

Tôi thường thấy if obj is None: bằng Python và gần đây tôi đã xem qua if obj is():. Vì tuple không thể thay đổi được, nó giống như một tối ưu hóa nội bộ hợp lý trong trình thông dịch Python để có bộ trống rỗng là một singleton, do đó cho phép sử dụng is thay vì yêu cầu ==. Nhưng điều này có được đảm bảo ở đâu đó không? Từ phiên bản nào của thông dịch viên?so sánh đối tượng với bộ trống rỗng với toán tử 'is' trong Python 2.x

[sửa] câu hỏi quan trọng bởi vì if() không phải là một singleton và có cách tạo ra một bộ trống với một địa chỉ khác, sau đó sử dụng is {} là một lỗi. Nếu nó chỉ được đảm bảo từ Python 2.x với x> 0, thì điều quan trọng là phải biết giá trị của x nếu bạn cần đảm bảo tính tương thích ngược của mã của bạn. Nó cũng quan trọng để biết nếu điều này có thể phá vỡ mã của bạn khi sử dụng PyPy/Jython/IronPython ...

+0

Đó chắc chắn không phải là thành ngữ. Có một trường hợp sử dụng hợp lý cho điều này? –

+0

@StevenRumbalski: không có trường hợp sử dụng đặc biệt nào. Tôi đã tìm thấy mã bằng cách sử dụng này, và nó đã cho tôi tự hỏi nếu tôi nên thay đổi nó trở lại, hoặc cập nhật ý kiến ​​của tôi về "là" nhà điều hành.Nó sẽ có ý nghĩa để thực hiện() như là một singleton ở cấp độ thông dịch viên ... –

Trả lời

11

Từ Python 2 docs và Python 3 docs:

... hai lần xuất hiện của tuple trống có thể hoặc có thể không mang lại cùng một đối tượng.

Nói cách khác, bạn không thể đếm số () is() để đánh giá là đúng.

0

Hãy sử dụng phương pháp id() để có được id nội bộ của():

>>> id(()) 
140180995895376 
>>> empty_tuple =() 
>>> id(empty_tuple) 
140180995895376  # same as the id of() 
>>> from copy import copy 
>>> id(copy(empty_tuple)) 
140180995895376  # still the same as the id of() 

Có vẻ như() được lưu trữ một cách hiệu quả như một singleton trong python (ít nhất là trong python> 2.6).

Có hành vi tương tự cho biến số trống "".

+0

Chỉ cần ra khỏi tò mò, những gì về '[]'? – Toomai

+0

ví dụ này chứng minh không có gì: nó không cho thấy rằng 2 bộ trống rỗng được tạo ra trong 2 mô-đun khác nhau sẽ là cùng một đối tượng cuối cùng. Chuỗi ký tự được thực hiện trong Python (nó là trường hợp từ đầu trong nhánh 2.x), và trong khi chuỗi rỗng cũng có thể là một singleton quá, không có bằng chứng rằng những gì bạn thấy không phải là một tác dụng phụ của interning. –

+0

@Toomai: danh sách có thể thay đổi, vì vậy bạn không thể có danh sách trống là một singleton. –

0

Đây là chi tiết triển khai CPython hiện tại không bảo đảm, vì vậy bạn sẽ không nhất thiết có thể dựa vào nó trong các triển khai Python khác, bao gồm Jython, IronPython, PyPy và các phiên bản tương lai của CPython.

Sử dụng is dường như là khoảng 0,04 μ s nhanh hơn trên hệ thống của tôi khi so sánh với một danh sách lớn:

$ python -m timeit -s "x = range(10000)" "x is()" 
10000000 loops, best of 3: 0.0401 usec per loop 

$ python -m timeit -s "x = range(10000)" "x ==()" 
10000000 loops, best of 3: 0.0844 usec per loop 

Tất nhiên nó có thể là tồi tệ hơn đáng kể nếu bạn đang so sánh với một cái gì đó với một tuỳ chỉnh __eq__() phương pháp:

$ python -m timeit -s $'import time\nclass X(object):\n def __eq__(self, other): return time.sleep(1)\nx = X()' "x ==()" 
10 loops, best of 3: 1e+03 msec per loop 

Tuy nhiên, nếu sự khác biệt về hiệu quả này rất quan trọng, tôi nghĩ điều đó sẽ dẫn đến vấn đề thiết kế.

0

Nó không phải về tối ưu hóa. Đó là về so sánh đối tượng. Python "is" được sử dụng để kiểm tra nhận diện đối tượng, sau đó so sánh bộ trống rỗng "()" là không bắt buộc để sử dụng toán tử "==". Trong thực tế, bất cứ điều gì trong python có thể được so sánh với "là".

>>> obj =() 
>>> obj is() 
True 
>>> isinstance(obj, tuple) 
True 
>>> obj is tuple 
False 
>>> type(obj) is tuple 
True 
>>> type(()) 
<type 'tuple'> 
>>> type(tuple) 
<type 'type'> 
>>> tuple == type(()) # value comparison with == 
True 

Tương tự cho bất kỳ giá trị khác:

>>> 333 is int 
False 
>>> type(333) is int 
True 
>>> isinstance(333, int) 
True 
+1

Nhưng so sánh với việc thực hiện các câu lệnh 'a = 257' và' b = 257'. 'a là b' có thể trả về' Sai'. –

+0

Có. Nhưng điều này liên quan đến python internals vì id (a) có thể khác với id (b). type (a) là kiểu (b) allways trả về True. Tôi đã cố gắng cho thấy rằng toán tử "is" phù hợp hơn với việc so sánh kiểu, mặc dù các đối tượng thể hiện cũng có thể được so sánh. –

+0

Điểm tuyệt vời: danh tính phải hoạt động khi so sánh các loại. Nhưng trong trường hợp đó, 'isinstance()' thường là điều đúng để sử dụng thay thế. –

Các vấn đề liên quan