仅当在try / except子句的范围内时,NoneType才不能下标错误

时间:2019-02-18 16:42:53

标签: python python-3.x flask sqlite

由于某种原因,当我运行以下脚本时,没有任何TypeError例外,并且我的应用程序运行没有问题。 (我将sqlite3用于数据库,将Flask用于应用程序本身。)

my_list = []
for dat in data:
    c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
    my_list.append(c.fetchone()[0])
 return my_list

似乎对于某些日期而言,没有任何数据,因此偶尔有NoneType是完全可能的。问题是,当我将代码更改为以下代码时,即会出现NoneType not subscriptable错误。

my_list = []
for dat in data:
    c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat))
    try:
        my_list.append(round(c.fetchone()[0]))
    except:
        my_list.append(c.fetchone()[0])
return my_list

假设,如果它遇到一个NoneType对象,它将分支到except子句,然后得到与原始代码块相同的结果。相反,我得到了这个错误,它破坏了我的Flask应用程序。如果有人可以解释发生了什么,那就太好了!

1 个答案:

答案 0 :(得分:1)

如果没有更多行要返回,则

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'spamfilter', 'USER': 'sa', 'PASSWORD': 'xxxxxxx', 'HOST': '192.168.2.10', # Or an IP Address that your DB is hosted on 'PORT': '49170', 'CONN_MAX_AGE': 60, } } 可以返回c.fetchone()。如果您的None查询仅产生一行,而如果SELECT引发了异常,则再次调用round() 可能会导致c.fetchone()None处理程序中返回。这里的问题是多次调用except 不会导致相同的第一行返回给后续调用。

调用一次c.fetchone(),并在执行任何操作之前测试它是否返回了c.fetchone()以外的值:

None

请注意,使用总括c.execute("""SELECT some_data FROM data_table WHERE date='{}'""".format(dat)) row = c.fetchone() if row is not None: try: my_list.append(round(row[0])) except ValueError: # value that can't be rounded continue 语句几乎总是一个坏主意。仅捕获预期的异常,仅此而已。您现在可以轻松地掩盖内存错误或阻止中断。

旁注:您对SQL injection attacks敞开大门。 不要使用字符串格式插入值,始终使用SQL参数来使数据库驱动程序适当地转义值:

except

c.execute("""SELECT some_data FROM data_table WHERE date=?""", (dat,)) 问号是一个SQL参数占位符,元组作为参数的第二个参数传入。