Поскольку вы ссылаетесь на HTML 4.01:
Это Логический атрибут . Обе формы являются правильными, но спецификация рекомендует использовать предыдущий .
Если вы использовали XHTML, то вы должны использовать более длинную версию .
HTML 5 также позволяет обе версии и удаляет рекомендацию для использования одного над другим (поскольку для совместимости с XHTML, который использовался как text / html, все современные браузеры могут обрабатывать оба синтаксиса ).
Логический AND (and
):
Возвращает первое значение False, если оно есть, else возвращает последнее значение в выражение
blockquote>Логическое ИЛИ (
or
):Возвращает первое значение Truthy, если оно есть, иначе верните последнее значение в выражении.
blockquote>
return len(args) and max(args) - min(args)
Является very питоновым лаконичным способом:
< blockquote>, если
blockquote>args
не пуст, верните результат изmax(args) - min(args)
.Операторы
and
иor
не ограничены работой или возвращающих логические значения. Здесь можно протестировать любой объект со значением правдоподобия. Это включает в себяint
,str
,list
,dict
,tuple
,set
,NoneType
и пользовательские объекты.Обратите внимание, что это более сжатый способ построения выражения
if-else
:return exp1 and exp2
Должен (грубо) перевести на:
r1 = exp1 if not r1: return r1 return exp2
Вот несколько примеров того, как и где эти конструкции могут использоваться для ручного ввода недопустимого ввода.
Пример с
and
(как показано OP)Возвращает разницу между
min
иmax
группы аргументов.def foo(*args): return len(args) and max(args) - min(args) foo(1, 2, 3, 4, 5) 4 foo() 0
Поскольку
and
, второе выражение также должно быть оценено, если первое -True
. Обратите внимание, что если первое выражение оценивается как Truthy, возвращаемый результат будет всегда результатом второго выражения .Если первое выражение оценивается как Falsey, тогда возвращаемый результат является результатом первого выражения.
Если
foo
принимает любые аргументы,len(args)
больше0
(положительное число), поэтому Возвращаемый результат -max(args) - min(args)
.Если
foo
не принимает аргументы,len(args)
-0
, который является Falsey, и возвращается0
.Обратите внимание, что альтернативным способом записи этой функции было бы следующее:
def foo(*args): if not len(args): return 0 return max(args) - min(args)
Пример с
or
Возвращает все числа над
9000
.def foo(*args): return [x for x in args if x > 9000] or 'No number over 9000!' foo(9004, 1, 2, 500) [9004] foo(1, 2, 3, 4) 'No number over 9000!'
В этом случае используется
or
. Если первым выражением является Truthy, то возвращаемый результат является результатом первого выражения. В противном случае оба выражения оцениваются, а результат возвращается в результате второго выражения.
foo
выполняет фильтрацию в списке, чтобы сохранить все числа над9000
. Если существуют такие числа, результатом понимания списка является непустой список, который является Truthy, поэтому он возвращается (здесь короткое замыкание в действии).Если таких чисел нет, то результатом списка comp является
[]
, который является Falsey. Итак, второе выражение теперь оценивается (непустая строка) и возвращается.И альтернативой для этой функции будет:
def foo(*args): r = [x for x in args if x > 9000] if not r: return 'No number over 9000!' return r
Цитирование из Документы Python
Обратите внимание, что ни
blockquote>and
, ниor
не ограничивают значение и тип, они возвращаются кFalse
иTrue
, а скорее вернет последний оцененный аргумент. Иногда это полезно, например, еслиs
- это строка, которая должна быть заменена значением по умолчанию, если оно пустое, выражениеs or 'foo'
дает требуемое значение.Итак, вот как Python был разработан для оценки булевых выражений, а приведенная выше документация дает нам представление о том, почему они это сделали.
Чтобы получить логическое
return bool(len(args) and max(args)-min(args))
Почему?
Короткое замыкание.
Например:
2 and 3 # Returns 3 because 2 is Truthy so it has to check 3 too 0 and 3 # Returns 0 because 0 is Falsey and there's no need to check 3 at all
То же самое также для
or
, то есть он вернет выражение, которое является Truthy , как только оно его обнаружит, потому что оценка остальной части выражения является избыточной.Вместо этого возвращаемого хардкора
True
илиFalse
, Python возвращает Truthy или Falsey , которые в любом случае будут оцениваться с помощьюTrue
илиFalse
. Вы можете использовать выражение как есть, и оно все равно будет работать.
Чтобы узнать, что Truthy и Falsey , проверьте Patrick Ответ Хау
Да. Это правильное поведение и сравнение.
По крайней мере, в Python A and B
возвращает B
, если A
по существу True
, в том числе, если A
NOT Null, NOT None
НЕ пустой контейнер (например, пустой list
, dict
и т. Д.). A
возвращается IFF A
по существу False
или None
или Empty или Null.
С другой стороны, A or B
возвращает A
, если A
по существу True
, в том числе, если A
НЕ НУЛЬНО, NOT None
NOT Пустое контейнер (например, пустой list
, dict
и т. д.), в противном случае он возвращает B
.
Легко не заметить (или игнорировать) это поведение, потому что в Python любой непустой объект non-null
оценивается как True, обрабатывается как логическое.
Для Например, все следующие будут печатать «True»
if [102]:
print "True"
else:
print "False"
if "anything that is not empty or None":
print "True"
else:
print "False"
if {1, 2, 3}:
print "True"
else:
print "False"
С другой стороны, все следующие будут печатать «False»
if []:
print "True"
else:
print "False"
if "":
print "True"
else:
print "False"
if set ([]):
print "True"
else:
print "False"
Да, есть несколько gotchas.
fn() == fn(3) == fn(4, 4)
Во-первых, если fn
возвращает 0
, вы не можете знать если он был вызван без какого-либо параметра, с одним параметром или с несколькими равными параметрами:
>>> fn()
0
>>> fn(3)
0
>>> fn(3, 3, 3)
0
fn
? Затем Python является динамическим языком. Он не указан нигде, что делает fn
, каким должен быть его вход и каким должен быть его выход. Поэтому очень важно правильно назвать функцию. Точно так же аргументы не должны называться args
. delta(*numbers)
или calculate_range(*numbers)
может лучше описать, что должна делать функция.
Наконец, предполагается, что логический оператор and
предотвращает отказ функции если вызывается без каких-либо аргументов. Он все еще терпит неудачу, если какой-то аргумент не является числом:
>>> fn('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fn
TypeError: unsupported operand type(s) for -: 'str' and 'str'
>>> fn(1, '2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fn
TypeError: '>' not supported between instances of 'str' and 'int'
>>> fn('a', 'b')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fn
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Вот способ записи функции в соответствии с «Легче спросить для прощения, чем разрешения ». Принцип :
def delta(*numbers):
try:
return max(numbers) - min(numbers)
except TypeError:
raise ValueError("delta should only be called with numerical arguments") from None
except ValueError:
raise ValueError("delta should be called with at least one numerical argument") from None
В качестве примера:
>>> delta()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in delta
ValueError: delta should be called with at least one numerical argument
>>> delta(3)
0
>>> delta('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta('a', 'b')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta('a', 3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in delta
ValueError: delta should only be called with numerical arguments
>>> delta(3, 4.5)
1.5
>>> delta(3, 5, 7, 2)
5
Если вы действительно не хотите создавать исключение, когда delta
вызывается без каких-либо аргументов , вы можете вернуть некоторое значение, которое невозможно в противном случае (например, -1
или None
):
>>> def delta(*numbers):
... try:
... return max(numbers) - min(numbers)
... except TypeError:
... raise ValueError("delta should only be called with numerical arguments") from None
... except ValueError:
... return -1 # or None
...
>>>
>>> delta()
-1
и / или выполнять логическую логику, но при их сравнении они возвращают одно из фактических значений. При использовании и значения оцениваются в булевом контексте слева направо. 0, '', [], (), {} и None являются ложными в булевом контексте; все остальное истинно.
Если все значения истинны в булевом контексте и возвращают последнее значение.
>>> 2 and 5
5
>>> 2 and 5 and 10
10
Если какое-либо значение ложно в булевом контексте и возвращает первое ложное значение.
>>> '' and 5
''
>>> 2 and 0 and 5
0
Итак, код
return len(args) and max(args)-min(args)
возвращает значение max(args)-min(args)
, когда есть args else, он возвращает len(args)
, который равен 0.
Является ли этот легитимный / надежный стиль или есть какие-либо ошибки на этом?
blockquote>Это законно, это оценка короткого замыкания , где возвращается последнее значение.
Вы являетесь хорошим примером. Функция вернет
0
, если аргументы не переданы, и код не должен проверять частный случай отсутствия аргументов.Другим способом использования этого параметра является аргумент по умолчанию Нет аргументов для изменяемого примитива, например, пустой список:
def fn(alist=None): alist = alist or [] ....
Если какое-то неправдоподобное значение передается в
alist
по умолчанию используется пустой список, удобный способ избежать оператораif
и изменчивого аргумента аргумента по умолчанию
Является ли этот легитимный / надежный стиль или есть какие-либо ошибки на этом?
blockquote>Я хотел бы добавить к этому вопросу, что он не только законный и надежный, но и он ультра практичный. Вот простой пример:
>>>example_list = [] >>>print example_list or 'empty list' empty list
Поэтому вы действительно можете использовать его в своих интересах. Для того, чтобы быть таким, я вижу это:
Or
operatorОператор
or
Python возвращает первое значение Truth-y или последнее значение и останавливается
And
operatorОператор
and
Python возвращает первое значение False-y или последнее значение и останавливает. За сцены
В python все числа интерпретируются как
True
, за исключением 0. Поэтому, говоря:0 and 10
, это то же самое, что:
False and True
Который явно
False
. Поэтому логично, что он возвращает 0
if ... else (if ... else (if ... else (if ... else ...)))
можно просто переписать как... and ... and ... and ... and ...
, и в этот момент действительно становится трудно утверждать, что читаемость для обоих случаев. – coldspeed 30 October 2017 в 11:15