0

images在 for 循环的每次迭代中,我都将一个对象附加到列表(初始化为空)。我没有通过索引显式访问列表,我只是将一个对象附加到它,这就是为什么我莫名其妙地得到了IndexError: list index out of range回报。

这是堆栈跟踪:

  Traceback (most recent call last):
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/flask/app.py", line 1504, in wsgi_app
     response = self.full_dispatch_request()
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/flask/app.py", line 1264, in full_dispatch_request
     rv = self.handle_user_exception(e)
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/flask/app.py", line 1262, in full_dispatch_request
     rv = self.dispatch_request()
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/flask/app.py", line 1248, in dispatch_request
     return self.view_functions[rule.endpoint](**req.view_args)
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/newrelic-1.4.0.137-py2.7-linux-x86_64.egg/newrelic/api/object_wrapper.py", line 166, in __call__
     self._nr_instance, args, kwargs)
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/newrelic-1.4.0.137-py2.7-linux-x86_64.egg/newrelic/api/function_trace.py", line 81, in literal_wrapper
     return wrapped(*args, **kwargs)
   File "/mnt/www-data/run/backend/lib/python2.7/site-packages/newrelic-1.4.0.137-py2.7-linux-x86_64.egg/newrelic/api/name_transaction.py", line 58, in __call__
     return self._nr_next_object(*args, **kwargs)
   File "/mnt/www-data/run/backend/webservice/decorators/controller_wrapper.py", line 75, in decorated_function
     return _return(f(*args, body=body, **kwargs))
   File "/mnt/www-data/run/backend/webservice/decorators/controller_wrapper.py", line 90, in decorated_function
     r = f(*args, **kwargs)
   File "/mnt/www-data/run/backend/webservice/decorators/login_required.py", line 16, in decorated_function
     return f(*args, **kwargs)
   File "/mnt/www-data/run/backend/webservice/controllers/me/photos.py", line 28, in create_photo
     phs = photos.store_photos(g.user, data)
   File "/mnt/www-data/run/backend/evertale/tasks/photos.py", line 106, in store_photos
     images.append(entity)
  IndexError: list index out of range

以及 .../tasks/photos.py 的摘录,失败的行是 for 循环的最后一行:

def store_photos(user, photos, update=False):
    if type(photos) is dict:
        photos = [photos]

    images = []
    for pic in photos:
        if 'gps' in pic and pic['gps']:
            loc = Location(ts=long(pic['ts']), user=user, _latlon=pic['gps'])
            loc.save()
        image = None
        if 'data' in pic:
            image = _read_image_from_base64(pic['data'])
            image = _normalize_rotation(image)
        entity = _persist_entity(user, image, update, **pic)
        if image:
            file_name = _file_name(entity.id)
            _persist_file(image, file_name)
            thumb_photo(entity.id)
        images.append(entity)

    if len(images) > 1:
        return images
    elif len(images) == 1:
        return images[0]
    else:
        return []

有人知道为什么会这样吗?我无法调试它,因为代码在生产服务器上,而且在本地机器上测试时我从未遇到过类似的情况。

4

2 回答 2

3

我怀疑您服务器上的源代码自您启动以来已更改。事实上,我几乎可以肯定。

Python 字节码包含一个行号,当回溯发生时,该行号用于查找并显示未编译的源代码行。

但是,一旦将字节码加载到内存中,如果您要更改源文件,它就不会重新加载。如果在服务器启动后从源文件中添加或删除行,回溯中的行将是错误的。

换句话说,您的回溯中显示的行几乎肯定不是发生错误的行。我当然不希望一个简单.append()抛出那个异常。特定异常 ( list index out of range) 仅在尝试通过__getattr__lst[index]操作)查找列表中的特定条目时发生。

于 2012-09-07T16:39:00.737 回答
2

Martijn 可能是对的,但还有另一种可能性。

如果在 之前调用的最后一个函数.append()是用 C 编码的(要么 要么_persist_entity()thumb_photo(),或者其中一个所做的最后一件事是调用用 C 编码的东西,并且 C 代码未能正确检查和处理错误,那么您最终可能会处于以下状态已引发异常但未识别。在这种情况下,附加调用可能会识别出已引发异常,即使它本身并未引发异常。

于 2012-09-07T16:45:08.590 回答