Это - плохая практика для возврата Исключений из методов

См. Также этот о том, как получить значения TF-IDF для всех документов:

feature_names = tf.get_feature_names()
doc = 0
feature_index = X[doc,:].nonzero()[1]
tfidf_scores = zip(feature_index, [X[doc, x] for x in feature_index])
for w, s in [(feature_names[i], s) for (i, s) in tfidf_scores]:
    print w, s

this 0.448320873199
is 0.448320873199
very 0.448320873199
strange 0.630099344518

#and for doc=1
this 0.448320873199
is 0.448320873199
very 0.448320873199
nice 0.630099344518

Я думаю, что результаты нормированы документом:

>>> 0.448320873199 2 + 0.448320873199 2 + 0.448320873199 2 + 0.630099344518 2 0.9999999999997548

12
задан ROMANIA_engineer 21 October 2017 в 09:12
поделиться

14 ответов

Если вы имеете в виду что-то вроде ...

public Exception MyMethod( string foo )
{
   if( String.IsNullOrEmpty() )
   {
      return new ArgumentNullException( "foo" );
   }
}

... а не ...

public void MyMethod( string foo )
{
   if( String.IsNullOrEmpty() )
   {
      throw new ArgumentNullException( "foo" )
   }
}

Тогда абсолютно нет, это не нормально. Вы бы полностью заново изобрели цель исключения и использовали бы ее как результат. Вот несколько стандартных передовых практик .

Еще одна веская причина не делать этого - стандартные делегаты больше не будут соответствовать вашей сигнатуре метода. Так, например, вы больше не можете использовать Action в MyMethod, и вместо этого вам нужно будет использовать Func .

@Andy, per comment, ответ слишком длинный для комментария: Не совсем. Не беспокойтесь о звонящем. В любом случае он должен защищаться в своем замысле. Подумайте о семантике исключения ... " будь хорошим гражданином коробки, изящно заверши заявку и живи, чтобы бороться в другой день. Не будьте эгоистичны и пытайтесь скрыть ошибки для звонящего. Защищайтесь, и он сделает то же самое. :)

Проверьте Блок обработки исключений корпоративной библиотеки . Думаю, они действительно формулируют отличное видение того, как работать с исключениями в вашей архитектуре.

32
ответ дан 2 December 2019 в 02:51
поделиться

Исключения только для исключительных ситуаций. Оставьте это тому, кто вызвал исключительный случай (вызывающий), чтобы решить проблему. Скажем, если у вас есть метод, который делит два числа, например

int Div(int x, int y)
{
return x/y;
}

, как бы вы реализовали правильную обработку ошибок для этого метода? Какое значение вы бы вернули вызову в следующих случаях?

Div(10,0);
or(int.MinValue,-1); //result of int.MinValue == int.MaxValue + 1;

В двух случаях нет «правильного» действия, это зависит от использования метода. Обычно рекомендуется прерывать выполнение кода при возникновении неожиданной ситуации.

Обработка ошибок больше, чем try {] catch {} . Что бы ни попало в блок catch, необходимо принять разумное решение на основе ошибки. Просто перехватить исключение и вернуть его не является обработкой ошибок; это скрытие симптомов, что в лучшем случае сделает отладку очень сложной, а зачастую и кошмарной.

1
ответ дан 2 December 2019 в 02:51
поделиться

Исключения могут быть приятными в некоторых настройках, но имейте в виду, что они могут значительно снизить производительность.

0
ответ дан 2 December 2019 в 02:51
поделиться

Если вы беспокоитесь о том, что другие программисты не поймают их, вы можете использовать инструменты анализа кода, чтобы убедиться, что все исключения перехватываются. Можно даже написать собственные атрибуты для достижения чего-то вроде проверенных исключений в Java.

Сказав это, не проще ли следовать общепринятым соглашениям и просто генерировать исключение? Если вы поместите это в комментарий функции, этого должно быть достаточно. Если вы думаете о некоторых конкретных программистах, которые не ловят исключения, вы имеете дело с PKBAC .

1
ответ дан 2 December 2019 в 02:51
поделиться

Нет, я не считаю это хорошей практикой.

Исключения хорошо названы: они должны быть исключительными обстоятельствами, а не нормой. Невозможно написать функцию таким образом, потому что вы не можете вернуть результаты вычислений, если возвращаете исключение.

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

Вы всегда можете избавить своих клиентов от необходимости писать блоки try / catch, выбрасывая непроверенные исключения.

1
ответ дан 2 December 2019 в 02:51
поделиться

Я никогда не видел метода, возвращающего исключение. Обычно метод возвращает значение, и этот метод может вызвать исключение. Но я никогда не видел кода с return new System.InvalidOperationException («Файл журнала не может быть доступен только для чтения»); например ...

Итак, чтобы ответить на ваш вопрос, я бы сказал, что да, это плохо ...

1
ответ дан 2 December 2019 в 02:51
поделиться

Я не уверен, что вред от возврата исключения, поскольку я делаю это, чтобы сообщить сообщение об исключении, тип и связанную информацию в журнал исключений. сервер sql.

Некоторые «исключения» например, соединение с sql-сервером не удалось сообщить о других исключениях, мне не нужно подниматься на другой уровень; Я могу просто попробовать записать их на сетевой диск, вместо того, чтобы сбой.

Другие типы исключений Я бы сразу же проверил, может ли метод, вызвавший функцию, справиться с этой конкретной проблемой без снижения производительности, связанного с ее вызовом.

В дополнение к этим методам я включаю логический параметр, который позволяет вызывающей стороне решить, следует ли генерировать исключение или просто вернуть его.

2
ответ дан 2 December 2019 в 02:51
поделиться

Возврат исключения в описанном вами сценарии - плохая идея, поскольку исключения не предназначены для этой цели.

Было бы лучше создать свою собственную структуру или класс, содержащий необходимую информацию, и вернуть ее вместо этого.

public enum MyErrorType
{
    Abc,
    Xyz,
    Efg
};

public struct Result
{
    public bool Success;
    public MyErrorType ErrorType;
};

, а затем метод:

private Result MyMethod()
{
   // code
}
5
ответ дан 2 December 2019 в 02:51
поделиться

Я должен согласиться что, в целом , это действительно плохая идея.

Однако , я могу придумать сценарий или два, где это могло бы иметь смысл.

Например, если вы разрабатываете проект библиотеки классов, вы можете захотеть создать свои собственные пользовательские исключения, и вы можете захотеть проделать некоторую дополнительную работу всякий раз, когда возникает одно из этих исключений (например, телефон домой, если пользователь разрешает это) .

Чтобы добиться этого, вы можете использовать заводской шаблон, таким образом, что только вы можете создавать их, и вы заставляете создание проходить через одно место (где также живет ваш код «домашнего телефона»).

В этом случае вам не нужно, чтобы фабрика сама генерировала исключение, потому что это отключит трассировку стека. Вместо этого он вернет его к исходному методу throw.

Но ситуации, подобные этой, являются исключением ** cough ** , а не правилом. Ни при каких обстоятельствах я не хочу видеть исключение, передаваемое через границы библиотеки классов, и ни при каких обстоятельствах я не буду создавать исключение, не будучи уверенным, что оно будет сгенерировано.

4
ответ дан 2 December 2019 в 02:51
поделиться

Определенно неортодоксальное использование исключений. Особенность, которая делает исключения мощными, заключается в том, что генерируемое исключение может всплывать на любое количество уровней в стеке вызовов. Если вы просто вернете его, вы потеряете это свойство (но также и связанное с ним негативное влияние на производительность).

Я действительно не понимаю, чем это отличается от простого возврата экземпляра класса, который содержит информацию о возможных ошибках. Единственное отличие состоит в том, что возвращение объектов, унаследованных от класса Exception, может вызвать некоторую путаницу у других разработчиков, которые прочитают ваш код позже.

Так что, хотя нет ничего плохого в возврате объектов, содержащих информацию об ошибках, я бы предложил использовать классы, которые не Для этой цели не наследуется от Exception, чтобы избежать путаницы.

6
ответ дан 2 December 2019 в 02:51
поделиться

Нет.

Исключения должны существовать только в исключительных случаях (отсюда и название). Единственный раз, когда я мог увидеть, что метод возвращает исключение, это какой-то тип фабричного метода, целью которого было именно создание исключения - но даже в этом случае он растягивает ситуацию.

Если вам нужно вернуть больше информации, чем логическое значение , создайте собственный класс (не производный от исключения), который включает ваше логическое значение + другую информацию.

6
ответ дан 2 December 2019 в 02:51
поделиться

Вы никогда не должны возвращать исключения. Вместо этого, если ваша функция достаточно сложна, создайте класс, который является результатом вашей функции. Например, метод GetPatientList возвращает GetPatientListResult. В нем мог быть член Успеха. Исключения составляют действительно необычные вещи, такие как исчезновение файла в середине операции, недопустимые или нулевые параметры, установленные для функции, выход базы данных из строя. Кроме того, это нарушает всю модель абстракции - Dog.GoForAWalk должен возвращать DogWalkReport, а не PossablyNullDogWalkException.

9
ответ дан 2 December 2019 в 02:51
поделиться

Нет, это полностью убивает язык (технологию, поскольку вы просто указываете .NET).

Я также не согласен с тем, что это упрощает использование ваших API для других, любому, кто изучил и имеет базовые представления о программировании с использованием модели, включающей исключения, будет труднее использовать ваш код.

Что произойдет, если в будущем вашему методу потребуется вернуть значение? Что делать, если существует более одного сценария ошибок? Если вы действительно хотите узнать больше о том, как прошел метод, вам необходимо создать класс, который инкапсулирует как результат, так и любую дополнительную информацию о состоянии, которую вы хотите.

2
ответ дан 2 December 2019 в 02:51
поделиться

Никто больше этого не сказал: Насколько я понимаю, в .NET трассировка стека исключения не заполняется до тех пор, пока исключение не будет выброшено . См. Лучшие методы обработки исключений , где говорится:

  • Трассировка стека начинается с оператора, в котором генерируется исключение, и заканчивается оператором catch, который перехватывает исключение. Помните об этом факте, решая, где разместить оператор throw.

  • Используйте методы построителя исключений. Класс обычно генерирует одно и то же исключение из разных мест в своей реализации. Чтобы избежать излишнего кода, используйте вспомогательные методы, которые создают исключение и возвращают его.

В .NET, если вы просто создаете экземпляр Exception и вернете его, у вас не будет никакой информации о стеке в этом Exception. Это преимущество, когда вы используете эту функцию для создания метода построения исключений, потеря, когда вы используете исключения так, как вы спрашиваете. Для сравнения, в Java информация о стеке добавляется при создании экземпляра исключения, независимо от того, было ли оно когда-либо выброшено.

Таким образом, в .NET, когда вы возвращаете исключение, которое никогда не создавалось, вы отказываетесь от самой трассировки стека, которая сообщает вам, где возникла проблема. Возможно, в данном случае вам все равно, но я подумал, что на это стоит обратить внимание.

Накладные расходы на производительность сгенерированного исключения достаточно малы в любой современной JVM и в любом последнем выпуске .NET. Возврат исключения вместо его выброса - по соображениям производительности - является неподходящей оптимизацией ... , если вы не профилировали свою программу и не обнаружили, что конкретный выброс действительно является узким местом, и что возвращение Exception имеет существенное значение. (Что бы меня удивило, но все возможно.)

Примечание. Допустим, вы создали метод, который иначе был бы void , который возвращает исключение при ошибке. Это означает, что если вы хотите проверить наличие ошибок, вы должны проверить null , чтобы узнать, была ли ошибка или нет. Как правило, методы, возвращающие значение null при ошибке, делают код уязвимым. Например, метод, возвращающий List, должен возвращать пустой List, а не null.

Также обратите внимание, что в .NET, когда вы повторно генерируете Exception, потому что стек заполняется в ] throw , вы обычно потеряете исходную трассировку стека. Чтобы избежать этого, используйте пустой throw без указания экземпляра Exception.

13
ответ дан 2 December 2019 в 02:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: