Попробуй питон кроме наконец - PullRequest
4 голосов
/ 18 декабря 2010

Похоже, я еще не совсем знаком с обработкой исключений. Я в недоумении :( Следующий код иногда возвращает эту ошибку:

File "applications/pingback/modules/plugin_h_pingback.py", line 190, in ping
    db(table.id==id_).update(status=status)
UnboundLocalError: local variable 'status' referenced before assignment

Я бы ожидал, что status всегда будет присвоено значение. Может ли быть, что выдается какое-то другое исключение (возможно, во внутреннем try) и finally затемняет его?

...
try:
    server_url = self._get_pingback_server(target)
except PingbackClientError, e:
    status = e.message
else:
    try:
        server = xmlrpclib.ServerProxy(server_url)
        status = server.pingback.ping(self.source, target)
    except xmlrpclib.Fault, e:
        status = e
finally:
    db(table.id==id_).update(status=status) # <-- UnboundLocalError
...

Спасибо, HC

Ответы [ 2 ]

9 голосов
/ 18 декабря 2010

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

try:
    server_url = self._get_pingback_server(target)
except PingbackClientError, e:
    # If evaluating `e.message` raises an exception then status is not set.
    status = e.message  # <--- here
else:
    try:
        # If either of these two lines fails with something other than
        # xmlrcplib.Fault, then status is not set.
        server = xmlrpclib.ServerProxy(server_url)             # <--- here
        status = server.pingback.ping(self.source, target)     # <--- here
    # If xmlrpclib.Fault is not defined status is not set.
    except xmlrpclib.Fault, e:                                 # <--- here
        status = e
finally:
    db(table.id==id_).update(status=status)

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

3 голосов
/ 18 декабря 2010

Как простое решение, я бы инициализировал статус вне любых блоков:

status = None
try: 
    # etc

Тогда статус всегда будет связан. Это не решит проблему любого необработанного исключения, но решит UnboundLocalError.

(Кроме того, в первом блоке, в котором вы устанавливаете статус с помощью e.message, в следующем блоке вы просто используете полную ошибку e, а не просто сообщение.)

...