Có lẽ cách tốt nhất là sử dụng toán tử not
:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
Vì vậy, thay vì mã của bạn:
if bool == True:
return False
else:
return True
Bạn đã có thể sử dụng:
return not bool
Sự phủ định lôgic như một chức năng
Ngoài ra còn có hai hàm trong operator
mô-đun operator.not_
và đó là bí danh operator.__not__
trong trường hợp bạn cần nó dưới dạng hàm thay vì dưới dạng toán tử:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
Những điều này có thể hữu ích nếu bạn muốn sử dụng một hàm yêu cầu một hàm vị từ hoặc một hàm gọi lại.
Ví dụ map
hoặc filter
:
>>> lst = [True, False, True, False]
>>> list(map(operator.not_, lst))
[False, True, False, True]
>>> lst = [True, False, True, False]
>>> list(filter(operator.not_, lst))
[False, False]
Tất nhiên, điều tương tự cũng có thể đạt được với một lambda
chức năng tương đương :
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
Không sử dụng toán tử đảo ngược bitwise ~
trên boolean
Người ta có thể muốn sử dụng toán tử đảo ngược bit ~
hoặc hàm toán tử tương đương operator.inv
(hoặc một trong 3 bí danh khác ở đó). Nhưng vì bool
là một lớp con của int
kết quả có thể không mong muốn vì nó không trả về "inverse boolean", nó trả về "số nguyên nghịch đảo":
>>> ~True
-2
>>> ~False
-1
Đó là bởi vì True
tương đương với 1
và False
đến 0
và nghịch đảo bit hoạt động dựa trên biểu diễn theo chiều bit của các số nguyên 1
và 0
.
Vì vậy, những điều này không thể được sử dụng để "phủ định" a bool
.
Phủ định với mảng NumPy (và các lớp con)
Nếu bạn đang xử lý mảng NumPy (hoặc các lớp con như pandas.Series
hoặc pandas.DataFrame
) có chứa boolean, bạn thực sự có thể sử dụng toán tử nghịch đảo bit ( ~
) để phủ định tất cả boolean trong một mảng:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
Hoặc hàm NumPy tương đương:
>>> np.bitwise_not(arr)
array([False, True, False, True])
Bạn không thể sử dụng not
toán tử hoặc operator.not
hàm trên các mảng NumPy vì chúng yêu cầu chúng trả về một hàm duy nhất bool
(không phải mảng boolean), tuy nhiên NumPy cũng chứa một hàm không logic hoạt động theo phần tử:
>>> np.logical_not(arr)
array([False, True, False, True])
Điều đó cũng có thể được áp dụng cho các mảng không phải boolean:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
Tùy chỉnh các lớp học của riêng bạn
not
hoạt động bằng cách gọi bool
giá trị và phủ định kết quả. Trong trường hợp đơn giản nhất, giá trị true sẽ chỉ gọi __bool__
đối tượng.
Vì vậy, bằng cách triển khai __bool__
(hoặc __nonzero__
trong Python 2), bạn có thể tùy chỉnh giá trị sự thật và do đó kết quả của not
:
class Test(object):
def __init__(self, value):
self._value = value
def __bool__(self):
print('__bool__ called on {!r}'.format(self))
return bool(self._value)
__nonzero__ = __bool__
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
Tôi đã thêm một print
tuyên bố để bạn có thể xác minh rằng nó thực sự gọi phương thức:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
Tương tự như vậy, bạn có thể triển khai __invert__
phương pháp để triển khai hành vi khi ~
được áp dụng:
class Test(object):
def __init__(self, value):
self._value = value
def __invert__(self):
print('__invert__ called on {!r}'.format(self))
return not self._value
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
Một lần nữa với một print
cuộc gọi để thấy rằng nó thực sự được gọi là:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
Tuy nhiên, việc triển khai __invert__
như vậy có thể gây nhầm lẫn vì hành vi của nó khác với hành vi Python "bình thường". Nếu bạn từng làm điều đó, hãy ghi lại rõ ràng nó và đảm bảo rằng nó có một trường hợp sử dụng khá tốt (và phổ biến).
int
vàbool
đều là tên nội trang (cho các loại mà chúng đại diện), và không được sử dụng làm tên biến.