Могу ли я использовать:
if A:
вместо того
if A is not None:
Последнее кажется таким многословным. Есть ли разница?
Заявление
if A:
будет вызывать A.__nonzero__()
(см. документацию по именам специальных методов ) и использовать возвращаемое значение этой функции. Вот резюме:
object.__nonzero__(self)
Вызывается для выполнения проверки истинности значения и встроенной операции
bool()
; должен вернутьFalse
илиTrue
, или их целочисленные эквиваленты0
или1
. Когда этот метод не определен,__len__()
вызывается, если он определен, и объект считается истинным, если его результат ненулевой. Если класс не определяет ни то,__len__()
ни другое__nonzero__()
, все его экземпляры считаются истинными.
С другой стороны,
if A is not None:
сравнивает только ссылку A
с тем, None
чтобы увидеть, является ли это то же самое или нет.
A is not None
быстрее, так как работы намного меньшеif object(): pass
~ 0,130 мксек на цикл, аif object() is not None: pass
~ 0,135 мксек. В любом случае, вам не следует использовать производительность, чтобы выбирать между этими двумя, а скорее смотреть на различия в том, как они работают, поскольку они не эквивалентны .if A is not None
кажется, медленнее, потому что это сравнение, и ему нужно загрузить встроенный синглтонNone
в качестве промежуточного шага для сравненияA
(взгляните наdis.dis()
). Поправь меня, если я ошибаюсь, но,if A:
кажется, это более эффективно, как только ты действительно хочешь проверить ценность истины, а неNone
личность.python -m timeit -s"a=0" "if a: pass" "else: pass"
быстрее,python -m timeit -s"a=0" "if a is None: pass" "else: pass"
ноpython -m timeit -s"a=1" "if a: pass" "else: pass"
медленнее. Может зависеть от платформы, посмотреть, если вы получите те же результатыis None
тест был действительно самым медленным для меня. В pypy они все измерены абсолютно одинаково :)Как написано в PEP8 :
источник
None
, а просто проверкой истинности. В этом случаеif A:
кажется более эффективным (принятьdis.dis()
, есть дополнительные шаги загрузки встроенногоNone
и сравнения, сif A is not None:
, в то время как есть толькоjump_if
в другом случае).так что это не то же самое, что
источник
Многие функции возвращают None, если нет подходящих результатов. Например,
.first()
метод запроса SQLAlchemy возвращает None, если в результате не было строк. Предположим, вы выбираете значение, которое может возвращать 0, и вам необходимо знать, действительно ли оно равно 0 или запрос не дал результатов вообще.Распространенной идиомой является присвоение необязательному аргументу функции или метода значения по умолчанию None, а затем проверка значения None, чтобы убедиться, что оно указано. Например:
сравните это с:
В последнем случае, что произойдет, если вы позвоните
spam(0)
илиspam([])
? Функция (неправильно) обнаружит, что вы не передали значение,eggs
и вычислит значение по умолчанию для вас. Это, вероятно, не то, что вы хотите.Или представьте себе такой метод, как «вернуть список транзакций для данного аккаунта». Если аккаунт не существует, он может вернуть None. Это отличается от возврата пустого списка (что означало бы, что «эта учетная запись существует, но не записала транзакции).
Наконец, вернемся к материалам базы данных. Существует большая разница между NULL и пустой строкой. Пустая строка обычно говорит: «здесь есть значение, а это значение вообще ничего». NULL говорит: «это значение не было введено».
В каждом из этих случаев вы бы хотели использовать
if A is None
. Вы проверяете конкретное значение - None - не просто «любое значение, приведенное к False».источник
Они делают разные вещи .
Приведенные ниже проверки , если А имеет ничего , кроме значений
False
,[]
,None
,''
и0
. Проверяет значение А.Ниже проверяется, является ли объект A отличным от None. Он проверяет и сравнивает ссылку (адрес памяти) A и None.
ОБНОВЛЕНИЕ: дальнейшее объяснение
Часто кажется, что они делают одно и то же, поэтому многие люди используют их взаимозаменяемо - это действительно плохая идея. Причина, по которой эти два результата дают одни и те же, много раз по чистой случайности из-за оптимизаций интерпретатора / компилятора, таких как интернирование или что-то еще.
С учетом этих оптимизаций целые и строки одного и того же значения в конечном итоге используют одно и то же пространство памяти. Это, вероятно, объясняет, почему две отдельные строки действуют так, как если бы они были одинаковыми.
Другие вещи не ведут себя так же, хотя ..
У двух списков явно есть своя память. Удивительно, но кортежи ведут себя как строки.
Вероятно, это потому, что кортежи гарантированно не изменятся, поэтому имеет смысл повторно использовать одну и ту же память.
Суть в том, что нельзя полагаться на совпадения . То, что это крякает как утка, не означает, что это утка. Используйте
is
и в==
зависимости от того, что вы действительно хотите проверить. Эти вещи трудно отладить, такis
как они читаются как проза, и мы часто просто просматриваем их.источник
None
это синглтон, это не деталь реализации (в отличие от int или интернирования строк). Я не уверен, что понимаю, что вы имеете в виду.None
ведет себя иначе, чемint
илиstr
из-за интернирования. Моя точка зрения в том, чтоis
и==
проверяют разные вещи; первый проверяет адрес памяти, второй проверяет содержимое адресов памяти.if A:
будет иметь значение false, если A равно 0, False, пустая строка, пустой список или None, что может привести к нежелательным результатам.источник
Большинство руководств, которые я видел, предлагают вам использовать
если:
если у вас нет причин быть более конкретными.
Есть небольшие отличия. Существуют значения, отличные от None, которые возвращают False, например, пустые списки или 0, поэтому подумайте, что именно вы проверяете.
источник
None - это специальное значение в Python, которое обычно обозначает неинициализированную переменную. Чтобы проверить, нет ли у A конкретного значения, которое вы используете:
Значения Falsey - это особый класс объектов в Python (например, false, []). Чтобы проверить, является ли A ложным, используйте:
Таким образом, эти два выражения не совпадают, и вам лучше не рассматривать их как синонимы.
PS Нет, это тоже фальшивка, поэтому первое выражение подразумевает второе. Но вторая охватывает другие значения фальши, кроме None. Теперь ... если вы можете быть уверены, что у вас не может быть других значений Falsey, кроме None в A, то вы можете заменить первое выражение вторым.
источник
Это зависит от контекста.
Я использую,
if A:
когда я ожидаю,A
что будет какая-то коллекция, и я хочу выполнить блок, только если коллекция не пустая. Это позволяет вызывающей стороне передавать любую коллекцию с хорошим поведением, пустую или нет, и делать так, как я ожидаю. Это также позволяетNone
иFalse
подавлять выполнение блока, что иногда удобно для вызова кода.OTOH, если я ожидаю,
A
что какой-то совершенно произвольный объект, но он мог бы быть по умолчаниюNone
, то я всегда используюif A is not None
, так как вызывающий код мог преднамеренно передать ссылку на пустую коллекцию, пустую строку или 0-значный числовой тип, или логическийFalse
, или некоторый экземпляр класса, который оказывается ложным в логическом контексте.И с другой стороны, если я ожидаю, что
A
это будет более конкретная вещь (например, экземпляр класса, для которого я собираюсь вызывать методы), но его можно было бы использовать по умолчаниюNone
, и я считаю, что логическое преобразование по умолчанию является свойство класса, которое я не прочь применить на всех подклассах, тогда я просто буду использовать,if A:
чтобы избавить мои пальцы от ужасного бремени ввода дополнительных 12 символов.источник
Я создал файл с именем
test.py
и запустил его на интерпретаторе. Вы можете изменить то, что хотите, чтобы точно проверить, как идут дела за кулисами.В этом отличие ассемблера:
Источник:
источник
Первый более Pythonic (лучший идеоматический код), но не будет выполнять блок, если A False (не None).
источник
is/is not None
. Следующий PEP8 - Pythonic. К тому же два теста разные .python> = 2.6,
если мы напишем такие как
будет генерировать предупреждение как,
Таким образом, мы можем использовать
источник