Некоторые другие ответы уже указали на модуль traceback .
Обратите внимание, что при использовании print_exc
в некоторых угловых случаях вы не получите того, чего ожидаете. В Python 2.x:
import traceback
try:
raise TypeError("Oups!")
except Exception, err:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_exc()
... будет отображать трассировку последнего исключения :
Traceback (most recent call last):
File "e.py", line 7, in
raise TypeError("Again !?!")
TypeError: Again !?!
Если вам действительно нужно получить доступ к исходному traceback . Одним из решений является кэширование информации об исключении , возвращенной из exc_info
, в локальную переменную и отображение ее с помощью print_exception
:
import traceback
import sys
try:
raise TypeError("Oups!")
except Exception, err:
try:
exc_info = sys.exc_info()
# do you usefull stuff here
# (potentially raising an exception)
try:
raise TypeError("Again !?!")
except:
pass
# end of useful stuff
finally:
# Display the *original* exception
traceback.print_exception(*exc_info)
del exc_info
Производство:
Traceback (most recent call last):
File "t.py", line 6, in
raise TypeError("Oups!")
TypeError: Oups!
Несколько ловушек с этим, хотя:
Из документа sys_info
:
Присвоение возвращаемого значения traceback локальной переменной в функции, которая обрабатывает исключение, вызовет циклическую ссылку . Это предотвратит сбор мусора, на который ссылается локальная переменная в той же функции или трассировка. [...] Если вам нужна трассировка, обязательно удалите ее после использования (лучше всего делать с помощью оператора try ... finally)
, но из того же документа:
Начиная с Python 2.2, такие циклы автоматически восстанавливаются , когда сборка мусора включена и становится недоступной, но она остается более эффективной для избегайте создания циклов.
С другой стороны, предоставляя вам доступ к трассировке , связанной с исключением, Python 3 дает менее удивительный результат:
import traceback
try:
raise TypeError("Oups!")
except Exception as err:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_tb(err.__traceback__)
... будет отображаться:
File "e3.py", line 4, in
raise TypeError("Oups!")
Я почти никогда не использую переменные повторно. Ненавижу говорить «никогда», но это почти никогда .
Вообще говоря, мне нравится, когда все переменные находятся вверху по той же причине, по которой мне нравится иметь раздел интерфейса на моих устройствах. Это похоже на реферат на бумаге - дайте мне общее представление о том, что происходит, без необходимости читать всю статью. Delphi может выиграть от возможности объявлять переменные во «внутренней области видимости», например, в цикле for или других блоках begin / end , но я не знаю, насколько это отвлечет от чистоты и удобочитаемости кода Delphi.
Вообще говоря, мне нравится, когда все переменные находятся вверху по той же причине, по которой мне нравится иметь раздел интерфейса на моих устройствах. Это похоже на реферат на бумаге - дайте мне общее представление о том, что происходит, без необходимости читать всю статью. Delphi может выиграть от возможности объявлять переменные во «внутренней области видимости», например, в цикле for или других блоках begin / end , но я не знаю, насколько это отвлечет от чистоты и удобочитаемости кода Delphi.
Вообще говоря, мне нравится, когда все переменные вверху, по той же причине, по которой мне нравится иметь раздел интерфейса на моих устройствах. Это похоже на реферат на бумаге - дайте мне общее представление о том, что происходит, без необходимости читать всю статью. Delphi может выиграть от возможности объявлять переменные во «внутренней области видимости», например, в цикле for или других блоках begin / end , но я не знаю, насколько это отвлечет от чистоты и удобочитаемости кода Delphi.
Мне нравится, когда все переменные находятся вверху, по той же причине, по которой мне нравится иметь раздел интерфейса на моих устройствах. Это похоже на реферат на бумаге - дайте мне общее представление о том, что происходит, без необходимости читать всю статью. Delphi может извлечь выгоду из возможности объявлять переменные во «внутренней области видимости», например, в цикле for или других блоках begin / end , но я не знаю, насколько это отвлечет от чистоты и удобочитаемости кода Delphi. Мне нравится, когда все переменные находятся вверху, по той же причине, по которой мне нравится иметь раздел интерфейса на моих устройствах. Это похоже на реферат на бумаге - дайте мне общее представление о том, что происходит, без необходимости читать всю статью. Delphi может выиграть от возможности объявлять переменные во «внутренней области видимости», например, в цикле for или других блоках begin / end , но я не знаю, насколько это отвлечет от чистоты и удобочитаемости кода Delphi.Это просто вопрос дисциплины. Да, Delphi, вероятно, лучше обслужить встроенным объявлением переменных, но это не имеет большого значения. Просто убедитесь, что вы называете переменные описательно, и тогда будет неудобно использовать их неправильно. И, как сказал Стефан Эггермонт, если ваши методы действительно становятся такими длинными, это совсем другой запах кода.
Не совсем. Поскольку я делаю свои методы очень маленькими, недалеко находится раздел var. Поскольку размер моего метода значительно уменьшился со времен университета, я бы сказал, что ломаю его реже.
Я определенно склонен повторно использовать локальные переменные, такие как 'Findex' (или просто 'i'), если процедура имеет несколько отдельных итеративных секций к нему. Я думаю, это не лучшая практика, но я бы хотел думать, что действительно очевидно только то, где я это делаю, и, очевидно, использование не перекрывается.
Обычно не составляет большого труда вернуться к началу процедуры и ввести новые переменные, хотя я не знал о Ctrl-Shift-V (попробую позже!).
Будет интересно посмотреть, что говорят остальные. : -)
Я думаю, это не лучшая практика, но я бы хотел думать, что действительно очевидно только то, где я это делаю, и, очевидно, использование не перекрывается.Обычно не составляет большого труда вернуться к началу процедуры и ввести новые переменные, хотя я не знал о Ctrl-Shift-V (попробую позже!).
Будет интересно посмотреть, что говорят остальные. : -)
Я думаю, это не лучшая практика, но я бы хотел думать, что действительно очевидно только то, где я это делаю, и, очевидно, использование не перекрывается.Обычно не составляет большого труда вернуться к началу процедуры и ввести новые переменные, хотя я не знал о Ctrl-Shift-V (попробую это позже!).
Будет интересно посмотреть, что говорят остальные. : -)
Я не склонен повторно использовать локальные переменные в качестве общего правила безопасности. Мне очень нравятся новые живые шаблоны "var" в d2007 +. Просто введите var [tab], и появится всплывающая подсказка. Также проверьте Ctrl-Shift-D (другие упоминали Ctrl-Shift-V для локальных переменных), чтобы объявить поле.
Объявить переменные очень просто - иногда они создавались автоматически (шаблон цикла «для»), в других случаях вы можете просто использовать рефакторинг «Объявить переменную» (или «Добавить локальную переменную», если вы используете MMX - как и должно быть).
Я думаю, что delphi делает исключение из-за чрезмерного использования временных переменных. В большинстве случаев, когда я создаю функцию / процедуру, где я знаю, что мне потребуются циклы или временные строки, первое, что я делаю, - это создаю var i, j: integer; tmp: строка; и при необходимости добавьте другие :)
Как долгое время пользователь Delphi (начиная с версии 1.0), это основной то, что я ненавижу в Паскале. все другие современные языки поддерживают определение в момент использования, но Delphi сохраняется с раздела варом и Delphi программисты сохраняются в нелепых пальцах выходок, чтобы оправдать его.
Я, вероятно, обнаружил бы, что это большая проблема, если бы не было CTRL-SHIFT-V в качестве ярлыка для раздела VAR. Я не пишу здесь ГИГАНТНЫЕ методы, но иногда они выходят из-под контроля (и я, конечно, могу это оправдать), и это очень помогает. Я не уверен, что это ярлык от cnTools или GExperts, но они оба довольно полезны, и я бы порекомендовал их обоих.
Вы можете разработать свой собственный стиль кодирования, который использует переменные по мере необходимости. Обычно я использую уникальные вары (90%) с несколькими временными варами (10%), когда это необходимо.
Это зависит от характера var. Если это переменная, которая помогает поддерживать другой код (счетчик циклов, построение строк SQL и т. Д.), То временная переменная, которую вы можете использовать повторно, будет полезна. В этом случае ваши временные переменные полезны в качестве «одноразовых» переменных в разделах кода. Просто добавьте комментарий к вашим объявлениям var с указанием временных переменных.
т.е. // временные переменные используются повторно, как требуется в этой процедуре -> очистить / повторно инициализировать их после / перед использованием.
Кроме этого Я избегаю временных переменных и никогда не использую их для хранения важных данных. Затем следует использовать уникальную переменную, чтобы избежать путаницы и сделать код более понятным и понятным.
Чтобы ответить на вопрос, я повторно использую только временную переменную, обычно строку, и обычно только для получения небольшого улучшения производительности. Нет проблем с этим.