Мабуть, найкращим способом є використання оператора not
:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
Отже, замість вашого коду:
if bool == True:
return False
else:
return True
Ви можете використовувати:
return not bool
Логічне заперечення як функція
У operator
модулі також є дві функції, operator.not_
і це псевдонім, operator.__not__
якщо вам це потрібно як функція, а не як оператор:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
Вони можуть бути корисні, якщо ви хочете використовувати функцію, яка вимагає предикат-функції або зворотного виклику.
Наприклад map
або 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]
Звичайно, того ж можна також досягти за допомогою еквівалентної lambda
функції:
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
Не використовуйте побітовий оператор інвертування ~
на логічних значеннях
У когось може виникнути спокуса використовувати побітовий інверторний оператор ~
або еквівалентну функцію оператора operator.inv
(або один із інших 3-х псевдонімів). Але оскільки bool
підклас int
результату може бути несподіваним, оскільки він не повертає "зворотне логічне значення", він повертає "обернене ціле число":
>>> ~True
-2
>>> ~False
-1
Це тому , що True
еквівалентно 1
і False
до 0
і побітова інверсія діє на побітового поданні цілих чисел 1
і 0
.
Тому їх не можна використовувати для "заперечення" a bool
.
Заперечення масивів NumPy (і підкласів)
Якщо ви маєте справу з масивами NumPy (або підкласами типу pandas.Series
або pandas.DataFrame
), що містять логічні значення, ви можете насправді використовувати побітовий обернений оператор ( ~
), щоб заперечити всі логічні значення в масиві:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
Або еквівалентна функція NumPy:
>>> np.bitwise_not(arr)
array([False, True, False, True])
Ви не можете використовувати not
оператор або operator.not
функцію на масивах NumPy, оскільки вони вимагають, щоб вони повертали одиницю bool
(не масив булевих символів), однак NumPy також містить логічну функцію not, яка працює елементарно:
>>> np.logical_not(arr)
array([False, True, False, True])
Це також можна застосувати до небулевих масивів:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
Налаштування власних класів
not
працює, закликаючи bool
значення і заперечуючи результат. У найпростішому випадку значення істини буде просто викликати __bool__
об'єкт.
Отже, реалізуючи __bool__
(або __nonzero__
в Python 2), ви можете налаштувати значення істини і, отже, результат 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)
Я додав print
заяву, щоб ви могли переконатися, що вона дійсно викликає метод:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
Так само ви можете реалізувати __invert__
метод для реалізації поведінки, коли ~
застосовується:
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)
Знову ж із print
дзвінком, щоб побачити, що він насправді називається:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
Однак реалізація __invert__
подібного може заплутати, оскільки це поведінка відрізняється від "звичайної" поведінки Python. Якщо ви коли-небудь зробите це чітко задокументуйте і переконайтеся, що він має досить хороший (і поширений) варіант використання.
int
іbool
є обома вбудованими іменами (для типів, які вони представляють), і їх не слід використовувати як імена змінних.