Мабуть, найкращим способом є використання оператора 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є обома вбудованими іменами (для типів, які вони представляють), і їх не слід використовувати як імена змінних.