Полезный для парсинга аргументов хранимой процедуры: xp_sscanf
Считывает данные со строки в местоположения аргумента, определенные каждым аргументом формата.
следующий пример использует xp_sscanf для извлечения двух значений из исходной строки на основе их положений в формате исходной строки.
DECLARE @filename varchar (20), @message varchar (20)
EXEC xp_sscanf 'sync -b -fproducts10.tmp -rrandom', 'sync -b -f%s -r%s',
@filename OUTPUT, @message OUTPUT
SELECT @filename, @message
Вот набор результатов.
-------------------- --------------------
products10.tmp random
Вы часто слышите, что Python поощряет стиль EAFP («проще просить прощения, чем разрешения»), а не стиль LBYL («посмотрите перед собой прыжок"). Для меня это вопрос эффективности и удобочитаемости.
В вашем примере (скажем, что вместо возврата списка или пустой строки функция должна была возвращать список или None
), если вы ожидаете что в 99% случаев result
будет фактически содержать что-то повторяемое, я бы использовал подход try / except
. Будет быстрее, если исключения действительно будут исключительными. Если результат
равен Нет
более чем в 50% случаев, то, вероятно, лучше использовать , если
.
Чтобы подтвердить это с помощью нескольких измерений:
>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175
Так, в то время как оператор if
always стоит вам, можно почти бесплатно настроить блок try / except
. Но когда действительно возникает исключение
, стоимость намного выше.
Мораль:
try / except
для управления потоком , Exception
на самом деле являются исключительными. Из документов Python:
EAFP
Проще просить прощения, чем
, но это имеет смысл больше всего, когда Exception
на самом деле являются исключительными.Из документов Python:
EAFP
Проще просить прощения, чем
, но это имеет смысл больше всего, когда Exception
на самом деле являются исключительными.Из документов Python:
EAFP
Проще просить прощения, чем разрешение. Эта общая кодировка Python стиль предполагает наличие действительных ключи или атрибуты и уловки исключения, если предположение подтверждается ложный. Этот чистый и быстрый стиль характеризуется наличием множества
попробуйте
икроме операторов
. В техника контрастирует с LBYL стиль, общий для многих других языков например C.
Ваша функция не должна возвращать смешанные типы (например, список или пустую строку). Он должен возвращать список значений или просто пустой список. Тогда вам не нужно будет ничего тестировать, то есть ваш код сворачивается до:
for r in function():
# process items
Ваш второй пример неверен - код никогда не вызовет исключение TypeError, поскольку вы можете выполнять итерацию как по строкам, так и по спискам. Итерация по пустой строке или списку также допустима - тело цикла будет выполнено ноль раз.
Пожалуйста, игнорируйте мое решение, если предоставленный мной код неочевиден на первый взгляд, и вы должны прочитать объяснение после примера кода.
Могу ли я предположить, что «значение не возвращено» означает, что возвращаемое значение - None? Если да, или если «нет значения» имеет значение «Ложь» логическим образом, вы можете сделать следующее, поскольку ваш код по существу обрабатывает «нет значения» как «не повторять»:
for r in function() or ():
# process items
If function ()
возвращает то, что не соответствует действительности, вы перебираете пустой кортеж, т. е. не выполняете никаких итераций. По сути, это LBYL.
Что из следующего было бы более предпочтительным и почему?
В этом случае предпочтительнее «Посмотрите, прежде чем прыгать». При исключительном подходе ошибка TypeError может произойти где угодно в теле цикла, и ее поймают и выбросят, что не является тем, что вы хотите, и усложнит отладку.
(Я согласен с Брэндоном Корфманом: возвращение None для "без элементов" вместо пустого списка нарушается. Это неприятная привычка кодеров Java, которую не следует видеть в Python. или Java.)
В общем, у меня сложилось впечатление, что исключения должны быть зарезервированы для исключительных обстоятельств. Если ожидается, что результат
никогда не будет пустым (но может быть, например, в случае поломки диска и т. Д.), Второй подход имеет смысл. Если, с другой стороны, пустой результат
вполне разумен в нормальных условиях, проверка его с помощью оператора if
имеет больше смысла.
Я имел в виду (more общий) сценарий:
# keep access counts for different files
file_counts={}
...
# got a filename somehow
if filename not in file_counts:
file_counts[filename]=0
file_counts[filename]+=1
вместо эквивалента:
...
try:
file_counts[filename]+=1
except KeyError:
file_counts[filename]=1
Что касается производительности, использование блока try для кода, который обычно не вызывает исключения быстрее, чем использование оператора if каждый раз. Итак, решение зависит от вероятности исключительных случаев.
Как правило, вы не должны никогда использовать try / catch или какие-либо средства обработки исключений для управления потоком. Несмотря на то, что итерация «за кулисами» управляется путем создания исключений StopIteration
,
bobince wisely points out that wrapping the second case can also catch TypeErrors in the loop, which is not what you want. If you do really want to use a try though, you can test if it's iterable before the loop
result = function();
try:
it = iter(result)
except TypeError:
pass
else:
for r in it:
#process items
As you can see, it's rather ugly. I don't suggest it, but it should be mentioned for completeness.