Спасибо, Шавенвартог. Ваш пример и справочная документация очень помогли. Моя реализация немного отличается, но очень близка к тому, что вы опубликовали:
from SomeProject import settings
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')
def get_thumbnail_url(self, obj):
return '%s%s' % (settings.MEDIA_URL, obj.thumbnail)
class Meta:
model = Project
fields = ('id', 'url', 'name', 'thumbnail_url')
Есть несколько способов заставить вашу программу завершиться. Какой из них подходит, зависит от того, почему вы хотите, чтобы ваша программа была прервана. В большинстве случаев это должно быть выполнением оператора return в вашей основной функции. Как в следующем.
int main()
{
f();
return 0;
}
Как уже определили другие, это позволяет должным образом уничтожить все ваши переменные стека, чтобы очистить их должным образом. Это очень важно.
Если вы обнаружили ошибку где-то глубоко в вашем коде и вам нужно выйти, вы должны выдать исключение, чтобы вернуться к основной функции. Как в следующем.
struct stop_now_t { };
void f()
{
// ...
if (some_condition())
throw stop_now_t();
// ...
}
int main()
{
try {
f();
} catch (stop_now_t& stop) {
return 1;
}
return 0;
}
Это приводит к разматыванию стека и разрушению всех ваших переменных стека. Все еще очень важно. Обратите внимание, что уместно указывать сбой с ненулевым возвращаемым значением.
Если в маловероятном случае, когда ваша программа обнаружит условие, которое указывает на то, что больше не безопасно выполнять больше операторов, вам следует использовать std :: abort (). Это приведет к внезапной остановке вашей программы без дальнейшей обработки. std :: exit () похож, но может вызывать обработчики atexit, что может быть плохо, если ваша программа достаточно загружена.
Разрешение потоку выполнения покинуть main
путем возврата значения или разрешение выполнения достигнуть конца функции - это способ, которым программа должна завершиться, за исключением случаев, когда невозможно исправить. Возвращать значение необязательно в C ++, но я обычно предпочитаю возвращать EXIT_SUCCESS
, найденное в cstdlib (специфичное для платформы значение, которое указывает, что программа успешно выполнена).
#include <cstdlib>
int main(int argc, char *argv[]) {
...
return EXIT_SUCCESS;
}
Если, однако, ваша программа достигает неисправимого состояния, она должна выдать исключение. Однако важно осознавать последствия этого. Нет общепринятых лучших практик для принятия решения о том, что должно или не должно быть исключением, но есть некоторые общие правила, о которых вам нужно знать.
Например, выбрасывать исключение из деструктора - почти всегда ужасная идея, потому что уничтожаемый объект мог быть уничтожен, потому что исключение уже было выброшено. Если выдается второе исключение, вызывается terminate
, и ваша программа останавливается без дальнейшей очистки. Вы можете использовать uncaught_exception
, чтобы определить, безопасно ли это, но обычно лучше не допускать, чтобы исключения выходили из деструктора.
Хотя обычно функции, которые вы вызываете, но не пишете, всегда позволяют генерировать исключения (например, new
выдает std::bad_alloc
, если не может выделить достаточно памяти), программистам-новичкам часто трудно сохранить отслеживать или даже знать обо всех специальных правилах, связанных с исключениями в C ++. По этой причине я рекомендую использовать их только в ситуациях, когда у вашей программы нет разумного способа продолжить выполнение.
#include <stdexcept>
#include <cstdlib>
#include <iostream>
int foo(int i) {
if (i != 5) {
throw std::runtime_error("foo: i is not 5!");
}
return i * 2;
}
int main(int argc, char *argv[]) {
try {
foo(3);
}
catch (const std::exception &e) {
std::cout << e.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
exit
является удержанием от C и может привести к тому, что объекты с автоматическим хранением не будут очищены должным образом. abort
и terminate
фактически заставляют программу совершить самоубийство и определенно не очистят ресурсы.
Что бы вы ни делали, не используйте исключения, exit
или abort
/ terminate
в качестве опоры для написания правильно структурированной программы. Сохраните их для исключительных ситуаций.
достаточно просто.
выход (0); } // конец функции
Убедитесь, что с обеих сторон от 0 есть пробел. Без пробелов программа не остановится.
отбросьте назад к основному, которое должно возвратить EXIT_FAILURE,
или станд.:: оконечный (), если повреждено.
(из комментария Martin York)