So sánh nếu hai biến tham chiếu cùng một đối tượng trong python


Câu trả lời:


133

Đó là những gì isdành cho: x is ytrả về Truenếu xylà cùng một đối tượng.


6
Trong ví dụ, x is ztrả về False. Nhưng nếu x và z được gán các giá trị giống nhau thay vì danh sách (ví dụ x, z = 13, 13) thì x is ztrả về True. Tại sao vậy?
Bill

12
@Bill: Đó là một đồ tạo tác về cách python xử lý các int. Python phân bổ các đối tượng số nguyên màxztrỏ đến. Vì các số nguyên nhỏ là lỗi phổ biến (-1 là giá trị lỗi, 0 bất kỳ lúc nào bạn thực sự lập chỉ mục một thứ gì đó, các số nhỏ thường là giá trị mặc định hợp lý) Python tối ưu hóa bằng cách phân bổ trước các số nhỏ (-5 đến 256) và sử dụng lại cùng một đối tượng số nguyên. Vì vậy, ví dụ của bạn chỉ hoạt động cho các số trong phạm vi này. Hãy thử gán một cái gì đó lớn hơn, tức là 270. Để biết thêm thông tin, hãy xem tại đây
ted vào

1
@AndresR Không, điều đó là sai. iskiểm tra xem hai tên tham chiếu cùng một vị trí bộ nhớ. Nó không liên quan gì đến bản thân đối tượng. Thật dễ dàng để có các đối tượng bất biến như các chuỗi bằng nhau nhưng không được lưu trữ tại cùng một vị trí, ví dụ ''a'*10000 is 'a' * 10000là Sai.
Jochen Ritzel

1
@JochenRitzel Bạn hoàn toàn đúng, cảm ơn bạn vì nhận xét này! Vì vậy, tôi không hiểu những gì đang xảy ra với"af" is "af" hoặc () is ()... tại sao chúng chia sẻ cùng một vị trí bộ nhớ?
AndresR

2
@AndreasR Đối với các chuỗi / số theo nghĩa đen trong mã, trình biên dịch sẽ kiểm tra xem chúng chỉ tồn tại một lần và sử dụng lại chúng. Các giá trị đặc biệt như (), None, True, False, v.v. cũng được định nghĩa là các giá trị đơn. Trong quá trình thực thi, thời gian chạy cũng cố gắng sử dụng lại các số và chuỗi nhỏ, nhưng cuối cùng thì đó là sự cân bằng giữa tốc độ và bộ nhớ và điều gì sẽ xảy ra phụ thuộc vào cách thực hiện thời gian chạy Python.
Jochen Ritzel


11

Mặc dù hai giải pháp chính xác x is zid(x) == id(z)đã được đăng, tôi muốn chỉ ra một chi tiết triển khai của python. Python lưu trữ các số nguyên dưới dạng các đối tượng, như một sự tối ưu hóa, nó tạo ra một loạt các số nguyên nhỏ khi bắt đầu (-5 đến 256) và chỉ MỌI biến giữ một số nguyên có giá trị nhỏ cho các đối tượng được khởi tạo trước này. Thêm thông tin

Điều này có nghĩa là đối với các đối tượng số nguyên được khởi tạo với cùng một số nhỏ (-5 đến 256), việc kiểm tra xem hai đối tượng có giống nhau không sẽ trả về true ( ON C-Pyhon , theo như tôi biết thì đây là chi tiết triển khai ), trong khi đối với lớn hơn số này chỉ trả về true nếu một đối tượng được khởi tạo ở dạng đối tượng kia.

> i = 13
> j = 13
> i is j
True

> a = 280
> b = 280
> a is b
False

> a = b
> a
280
> a is b
True

python3,6: a = 98765; b = 98765; a là b => Đúng. Có điều gì đó đã thay đổi rõ ràng.
Mikhail Kalashnikov

@MikhailKalashnikov Không. Tôi đã thử nghiệm trên Python 3.6.2, điều này vẫn tồn tại.
nix

vẫn tồn tại trên python 3.7.7
Bill Huang

9

Bạn cũng có thể sử dụng id () để kiểm tra đối tượng duy nhất mà mỗi tên biến tham chiếu đến.

In [1]: x1, x2 = 'foo', 'foo'

In [2]: x1 == x2
Out[2]: True

In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)

In [4]: x2 = 'foobar'[0:3]

In [5]: x2
Out[5]: 'foo'

In [6]: x1 == x2
Out[6]: True

In [7]: x1 is x2
Out[7]: False

In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)

Lưu ý của @ ted về việc sử dụng id khá liên quan ở đây.
Leo Ufimtsev


2

Đây là từ docs.python.org: "Mọi đối tượng đều có danh tính, kiểu và giá trị. Danh tính của đối tượng không bao giờ thay đổi sau khi nó được tạo; bạn có thể coi nó như địa chỉ của đối tượng trong bộ nhớ. Toán tử 'is' so sánh danh tính của hai đối tượng; hàm id () trả về một số nguyên đại diện cho danh tính của nó. "

Rõ ràng mỗi khi bạn thay đổi giá trị, đối tượng được tạo lại như được chỉ ra bằng cách thay đổi danh tính. Dòng x = 3 theo sau là dòng x = 3,14 không có lỗi và cung cấp các danh tính, kiểu và giá trị khác nhau cho x.


1
Bắt doc xuất sắc.
prosti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.