Я использую Исключения в Python и при Исключительных, и при неисключительных обстоятельствах.
часто хорошо смочь использовать Исключение, чтобы указать, что "запрос не мог быть выполнен", в противоположность возвращению Ошибочного значения. Это означает, что Вы,/always/знают, что возвращаемое значение является правильным типом, вместо arbitarily Ни одного или NotFoundSingleton или чего-то. Вот хороший пример того, где я предпочитаю использовать обработчик исключений вместо условного выражения на возвращаемом значении.
try:
dataobj = datastore.fetch(obj_id)
except LookupError:
# could not find object, create it.
dataobj = datastore.create(....)
побочный эффект состоит в том, что, когда datastore.fetch (obj_id) выполняется, Вы никогда не должны проверять, не является ли его возвращаемое значение Ни одним, Вы получаете ту ошибку сразу бесплатно. Это в противоречии с аргументом, "Ваша программа должна смочь выполнить всю свою основную функциональность, не используя исключения вообще".
Вот другой пример того, где исключения 'исключительно' полезны для написания кода для контакта с файловой системой, которая не подвергается условиям состязания.
# wrong way:
if os.path.exists(directory_to_remove):
# race condition is here.
os.path.rmdir(directory_to_remove)
# right way:
try:
os.path.rmdir(directory_to_remove)
except OSError:
# directory didn't exist, good.
pass
Один системный вызов вместо два, никакое состояние состязания. Это - плохой пример, потому что, очевидно, это перестанет работать с OSError при большем количестве обстоятельств, чем каталог не существует, но это - 'достаточно хорошее' решение для многих плотно управляемых ситуаций.
Вы можете использовать Regex
, чтобы проверить, что это «^ [01] + $» (или лучше, «^ [01] {1,32} $» ) и , затем используйте Convert
?
конечно, исключения вряд ли в любом случае будут огромной проблемой! Неэлегантно? может быть. Но они работают.
Пример (отформатирован для вертикального пространства):
static readonly Regex binary = new Regex("^[01]{1,32}$", RegexOptions.Compiled);
static void Main() {
Test("");
Test("01101");
Test("123");
Test("0110101101010110101010101010001010100011010100101010");
}
static void Test(string s) {
if (binary.IsMatch(s)) {
Console.WriteLine(Convert.ToInt32(s, 2));
} else {
Console.WriteLine("invalid: " + s);
}
}
Спасибо за отличный и невероятно быстрый ответ!
К сожалению, мои требования изменились. Теперь пользователь может вводить практически любой формат. Двоичное, десятичное, шестнадцатеричное. Так что я решил попробовать - catch просто предоставляет самое простое и чистое решение.
Так что для удобства я публикую код, который использую сейчас. Я думаю, что это довольно ясно и даже несколько элегантно, по крайней мере, я так думаю ^^.
switch (format)
{
case VariableFormat.Binary:
try
{
result = Convert.ToInt64(value, 2)
}
catch
{
// error handling
}
break;
case VariableFormat.Decimal:
try
{
result = Convert.ToInt64(value, 10)
}
catch
{
// error handling
}
break;
case VariableFormat.Hexadecimal:
try
{
result = Convert.ToInt64(value, 16)
}
catch
{
// error handling
}
break;
}
Так что спасибо за то, что побудили меня использовать try-catch, я думаю, что это действительно улучшило читаемость моего кода.
Спасибо