твердження пітона з дужками і без них


104

Ось чотири прості виклики заяви:

>>> assert 1==2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert 1==2, "hi"
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError: hi

>>> assert(1==2)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AssertionError

>>> assert(1==2, "hi")

Зауважте, що останній не викликає помилки. Яка різниця між викликом затвердження з дужками чи без них, що викликає таку поведінку? Моя практика - використовувати дужки, але вищесказане говорить про те, що я не повинен.


Дякуємо за корисні відповіді. Відмінність між ключовими словами та вбудованими функціями здається тонким. Ось перелік ключових слів, для яких я вважаю, що парен слід залишити: docs.python.org/reference/lexical_analysis.html#keywords
gaefan

2
Одна відмінність полягає в тому, що ви можете переосмислити вбудовані функції, але не можете цього зробити за допомогою ключових слів (не те, що колишня - хороша ідея).
gaefan

Це не функція від розрізнення ключових слів, а функція виклику проти оператора . (наприклад, друк використовувався як заява і працював без дужок).
Томаш Гандор

Відповіді:


129

Останній assertдав би вам попередження ( SyntaxWarning: assertion is always true, perhaps remove parentheses?), якби ви провели його через повного перекладача, а не через IDLE. Тому щоassert це ключове слово, а не функція, ви фактично передаєте кортеж як перший аргумент, а другий аргумент залишаєте.

Нагадаємо, що непорожні кортежі оцінюють True, і оскільки повідомлення про твердження необов’язкове, ви по суті телефонували, assert Trueколи писали assert(1==2, "hi").


10
Причина цього не відбувається в assert (1==2)тому, що дужки навколо одного виразу не створюватимуть кортеж автоматично; ви отримаєте таку ж поведінку, як і №4, якби це зробили assert (1==2,). Те ж саме відбулося б, якби ви зробили print ('foo', 'bar')замість цього print 'foo', 'bar'; ви побачите вийшов кортеж
Майкл Мрозек,

Варто ще більше підкреслити, що твердження форми, assert(test, message)ймовірно, неправильні та, безумовно, заплутані. Парень немає!
tcarobruce

19
Отже, що є правильним способом відступу довгого твердження, wrt PEP8? Здається, неможливо.
stantonk


30

Якщо ви введете дужки туди, тому що ви хотіли затвердити багато рядків, альтернативою є поставити зворотну косу риску в кінці рядка так:

foo = 7
assert foo == 8, \
    "derp should be 8, it is " + str(foo)

Друкує:

AssertionError: "derp should be 8, it is 7

Чому цей пітон assertповинен відрізнятися від усього іншого:

Я думаю, що пітонічна ідеологія полягає в тому, що програма повинна самокорегуватися, не турбуючись про спеціальний прапор, щоб увімкнути твердження. Спокуса вимкнути твердження занадто велика, і, таким чином, вона застаріла.

Я поділяю ваше роздратування тим, що у python assertє унікальний синтаксис відносно всіх інших конструкцій програмування python, і цей синтаксис знову змінився з python2 на python3 і знову змінився з python 3.4 на 3.6. Зробити заяви твердження не назад сумісні з будь-якої версії до будь-якої іншої версії.

Це assertпостук по плечу, який є громадянином 3-го класу, він буде повністю видалений у python4, і, звичайно, знову в Python 8.1.


2
Чи є документ про те, що ми повинні використовувати замість твердження? Assert здається таким логічним іменем для перевірки, і він має бажану поведінку, наприклад, показувати спеціальне повідомлення при помилці.
AnneTheAgile

18

assert 1==2, "hi"аналізується як assert 1==2, "hi""hi" як другий параметр для ключового слова. Отже, чому це правильно дає помилку.

assert(1==2)розбирається як assert (1==2)ідентичний assert 1==2тому, що паролі навколо одного елемента не створюють кортеж, якщо немає кінцевої коми, наприклад (1==2,).

assert(1==2, "hi")аналізується як assert (1==2, "hi"), що не дає помилки, оскільки не порожній кортеж (False, "hi")не є помилковим значенням, а другий параметр не надається до ключового слова.

Не слід використовувати дужки, оскільки assertце не функція в Python - це ключове слово.


13

Ви можете порушити заяву про ствердження без \подібного:

foo = 7
assert foo == 8, (
    'derp should be 8, it is ' + str(foo))

Або якщо у вас є ще довше повідомлення:

foo = 7
assert foo == 8, (
    'Lorem Ipsum is simply dummy text of the printing and typesetting '
    'industry. Lorem Ipsum has been the industry\'s standard dummy text '
    'ever since the 1500s'
)

1
Цікава ідея. Я ненавиджу зворотні косої риси для продовження, і це альтернатива обгортці твердження у функції утиліти (що було моїм рішенням).
Томаш Гандор

1

Далі цитується з доктора python

Виписки звітів є зручним способом вставлення налагоджувальних тверджень у програму:

assert_stmt ::= "assert" expression ["," expression]

Проста форма, стверджуючи вираз, еквівалентна if __debug__: if not expression: raise AssertionError

Розширена форма, ствердження вираз1, вираз2 , еквівалентна if __debug__: if not expression1: raise AssertionError(expression2)

Таким чином, коли ви тут використовуєте круглі дужки, ви використовуєте просту форму, і вираз оцінюється як кортеж, що завжди відповідає дійсності при передачі на bool

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.