Попробуй еще Python - PullRequest
       29

Попробуй еще Python

493 голосов
/ 13 мая 2009

Как предполагается использовать необязательное предложение else оператора try?

Ответы [ 20 ]

3 голосов
/ 22 марта 2014

Большинство ответов, похоже, сосредоточены на том, почему мы не можем просто поместить материал в предложение else в самом предложении try. В вопросе предложение else в выражении try ... что это хорошо для , в частности, спрашивается, почему код предложения else не может идти после самого блока try, и этот вопрос дублируется этим , но я не вижу четкого ответа на этот вопрос здесь. Я чувствую, https://stackoverflow.com/a/3996378/1503120 превосходно отвечает на этот вопрос. Я также попытался объяснить различное значение различных статей в https://stackoverflow.com/a/22579805/1503120.

3 голосов
/ 15 мая 2009

Вот и все. Блок «else» предложения try-exc существует для кода, который выполняется, когда (и только когда) успешная операция выполняется. Его можно использовать и злоупотреблять.

try:
    fp= open("configuration_file", "rb")
except EnvironmentError:
    confdata= '' # it's ok if the file can't be opened
else:
    confdata= fp.read()
    fp.close()

# your code continues here
# working with (possibly empty) confdata

Лично мне это нравится и я использую его, когда это уместно. Семантически группирует утверждения.

2 голосов
/ 21 мая 2011

Возможно использование может быть:

#debug = []

def debuglog(text, obj=None):
    " Simple little logger. "
    try:
        debug   # does global exist?
    except NameError:
        pass    # if not, don't even bother displaying
    except:
        print('Unknown cause. Debug debuglog().')
    else:
        # debug does exist.
        # Now test if you want to log this debug message
        # from caller "obj"
        try:
            if obj in debug:
                print(text)     # stdout
        except TypeError:
            print('The global "debug" flag should be an iterable.')
        except:
            print('Unknown cause. Debug debuglog().')

def myfunc():
    debuglog('Made it to myfunc()', myfunc)

debug = [myfunc,]
myfunc()

Может быть, это тоже приведет вас к использованию.

1 голос
/ 21 ноября 2013

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

#in a long running loop
try:
    query = queue.get()
    conn = connect_to_db(<main db>)
    curs = conn.cursor()
    try:
        curs.execute("<some query on user input that may fail even if sanitized">)
    except DBError:
        logconn = connect_to_db(<logging db>)
        logcurs = logconn.cursor()
        logcurs.execute("<update in DB log with record of failed query")
        logcurs.close()
        logconn.close()
    else:

        #we can't put this in main try block because an error connecting
        #to the logging DB would be indistinguishable from an error in 
        #the mainquery 

        #We can't put this after the whole try: except: finally: block
        #because then we don't know if the query was successful or not

        logconn = connect_to_db(<logging db>)
        logcurs = logconn.cursor()
        logcurs.execute("<update in DB log with record of successful query")
        logcurs.close()
        logconn.close()
        #do something in response to successful query
except DBError:
    #This DBError is because of a problem with the logging database, but 
    #we can't let that crash the whole thread over what might be a
    #temporary network glitch
finally:
    curs.close()
    conn.close()
    #other cleanup if necessary like telling the queue the task is finished

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

1 голос
/ 30 июля 2013

Я нашел else полезным для работы с возможно неправильным файлом конфигурации:

try:
    value, unit = cfg['lock'].split()
except ValueError:
    msg = 'lock monitoring config must consist of two words separated by white space'
    self.log('warn', msg)
else:
     # get on with lock monitoring if config is ok

Исключение при чтении конфигурации lock отключает мониторинг блокировки, а ValueErrors записывает полезное предупреждающее сообщение.

1 голос
/ 02 апреля 2015

Предположим, что ваша логика программирования зависит от того, есть ли в словаре запись с заданным ключом. Вы можете проверить результат dict.get(key) с помощью конструкции if... else..., или вы можете сделать:

try:
    val = dic[key]
except KeyError:
    do_some_stuff()
else:
    do_some_stuff_with_val(val)
1 голос
/ 15 мая 2009

Блок else часто может существовать для дополнения функциональности, которая встречается в каждом блоке except.

try:
    test_consistency(valuable_data)
except Except1:
    inconsistency_type = 1
except Except2:
    inconsistency_type = 2
except:
    # Something else is wrong
    raise
else:
    inconsistency_type = 0

"""
Process each individual inconsistency down here instead of
inside the except blocks. Use 0 to mean no inconsistency.
"""

В этом случае inconsistency_type устанавливается в каждом блоке кроме, так что поведение дополняется в случае отсутствия ошибок в else.

Конечно, я описываю это как шаблон, который может когда-нибудь появиться в вашем собственном коде. В этом конкретном случае вы просто устанавливаете inconsistency_type на 0 перед блоком try.

1 голос
/ 13 апреля 2017

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

while True:
    try:
        r = random.random()
        some_operation_that_fails_for_specific_r(r)
    except Exception:
        continue
    else:
        break

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

1 голос
/ 13 декабря 2012

Вот еще одно место, где мне нравится использовать этот шаблон:

 while data in items:
     try
        data = json.loads(data)
     except ValueError as e:
        log error
     else:
        # work on the `data`
0 голосов
/ 13 мая 2009

Блок else: сбивает с толку и (почти) бесполезен. Это также часть операторов for и while.

На самом деле, даже в if заявлении о else: можно по-настоящему ужасно использовать, создавая ошибки, которые очень трудно найти.

Учтите это.

   if a < 10:
       # condition stated explicitly
   elif a > 10 and b < 10:
       # condition confusing but at least explicit
   else:
       # Exactly what is true here?
       # Can be hard to reason out what condition is true

Подумайте дважды о else:. Это вообще проблема. Избегайте его, за исключением случаев if, и даже тогда рассмотрите возможность документирования условия else, чтобы сделать его явным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...