Trong thử nghiệm đầu tiên, Python cố gắng chuyển đổi đối tượng thành giá trị bool
nếu nó chưa phải là một. Khoảng, chúng ta đang hỏi đối tượng: bạn có ý nghĩa hay không? này được thực hiện bằng cách sử dụng thuật toán sau đây:
Nếu đối tượng có một phương pháp đặc biệt __nonzero__
(cũng như số built-in, int
và float
), nó gọi phương pháp này. Giá trị này phải trả về giá trị bool
sau đó được sử dụng trực tiếp hoặc giá trị int
được coi là False
nếu bằng không.
Ngược lại, nếu đối tượng có một phương pháp đặc biệt __len__
(như làm thùng chứa được xây dựng-in, list
, dict
, set
, tuple
...), nó gọi phương pháp này, xem xét một container False
nếu nó là rỗng (chiều dài bằng không).
Nếu không, đối tượng được coi là True
trừ khi nó là None
trong trường hợp này, nó được coi là False
.
Trong thử nghiệm thứ hai, đối tượng được so sánh để bình đẳng với None
. Ở đây, chúng tôi đang yêu cầu đối tượng, "Bạn có bằng với giá trị khác này không?" này được thực hiện bằng cách sử dụng thuật toán sau đây:
Nếu đối tượng có một phương pháp __eq__
, nó được gọi, và giá trị trả về sau đó được chuyển thành một giá trị bool
và dùng để xác định kết quả của if
.
Nếu không, nếu đối tượng có phương thức __cmp__
, nó sẽ được gọi. Hàm này phải trả lại một số int
cho biết thứ tự của hai đối tượng (-1
nếu self < other
, 0
nếu self == other
, +1
nếu self > other
).
Nếu không, đối tượng sẽ được so sánh với danh tính (nghĩa là chúng được tham chiếu đến cùng một đối tượng, có thể được kiểm tra bởi toán tử is
).
Có thể thực hiện kiểm tra khác bằng toán tử is
. Chúng tôi sẽ hỏi đối tượng, "Bạn có phải là đối tượng cụ thể này không?"
Nói chung, tôi khuyên bạn nên sử dụng thử nghiệm đầu tiên với các giá trị không phải số, để sử dụng phép thử cho sự bình đẳng khi bạn muốn so sánh các đối tượng có cùng tính chất (hai chuỗi, hai số, ...) và chỉ kiểm tra danh tính khi sử dụng giá trị sentinel (None
có nghĩa là không được khởi tạo cho trường thành viên cho ví dụ hoặc khi sử dụng phương thức getattr
hoặc __getitem__
).
Nói tóm lại, chúng ta có:
>>> class A(object):
... def __repr__(self):
... return 'A()'
... def __nonzero__(self):
... return False
>>> class B(object):
... def __repr__(self):
... return 'B()'
... def __len__(self):
... return 0
>>> class C(object):
... def __repr__(self):
... return 'C()'
... def __cmp__(self, other):
... return 0
>>> class D(object):
... def __repr__(self):
... return 'D()'
... def __eq__(self, other):
... return True
>>> for obj in ['',(), [], {}, 0, 0., A(), B(), C(), D(), None]:
... print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
... (repr(obj), bool(obj), obj == None, obj is None)
'': bool(obj) -> False, obj == None -> False, obj is None -> False
(): bool(obj) -> False, obj == None -> False, obj is None -> False
[]: bool(obj) -> False, obj == None -> False, obj is None -> False
{}: bool(obj) -> False, obj == None -> False, obj is None -> False
0: bool(obj) -> False, obj == None -> False, obj is None -> False
0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
A(): bool(obj) -> False, obj == None -> False, obj is None -> False
B(): bool(obj) -> False, obj == None -> False, obj is None -> False
C(): bool(obj) -> True, obj == None -> True, obj is None -> False
D(): bool(obj) -> True, obj == None -> True, obj is None -> False
None: bool(obj) -> False, obj == None -> True, obj is None -> True
chung 'someobj là Không' là thích hợp hơn để 'someobj == Không' –
gì về giả nếu X không phải là Không? Hoặc 'X! = None'? –
câu hỏi này chi tiết hơn so với những người khác ... kudo ... – alamin