Python条件分支异常:if不满足时无法进入else语句
KeyError触发而非进入if-else的else分支问题解析
问题描述
使用try-except-else结构时,else块内的if-else分支出现异常:当目标键不存在时,未进入else分支,反而触发KeyError。相关代码如下:
try: symbol = input("Specify symbol: ").upper() dt_string = input("Specify datetime in isoformat (e.g.'2021-05-27T03:30:00+00:00'): ") try: dt = datetime.fromisoformat(dt_string) except Exception as e: print(e) ts = Decimal(input("Specify ticksize after: ")) except Exception as e: print(e) else: with open(join(file_directory, "ticksize_changes.json"), "r") as f: ts_dict = json.load(f) print(ts_dict) if ts_dict[symbol]: # if symbol exists in json file ts_dict[symbol].append({'datetime': dt_string, 'ts_after': ts}) else: ts_dict[symbol] = [{'datetime': dt_string, 'ts_after': ts}] with open(join(file_directory, "ticksize_changes.json"), "w") as f: json.dump(ts_dict, f, default=str)
错误表现:当symbol不存在于ts_dict的键中时,直接抛出KeyError,无法执行else分支的初始化逻辑。
问题根源
问题出在判断条件if ts_dict[symbol]:上:
当symbol不是ts_dict的键时,直接通过ts_dict[symbol]访问会立即抛出KeyError,程序根本无法完成“判断值是否为真”的步骤,自然跳不到后面的else分支。
解决方案
方案1:先检查键是否存在
用symbol in ts_dict替代直接访问,先确认键存在再操作值:
try: symbol = input("Specify symbol: ").upper() dt_string = input("Specify datetime in isoformat (e.g.'2021-05-27T03:30:00+00:00'): ") try: dt = datetime.fromisoformat(dt_string) except Exception as e: print(e) ts = Decimal(input("Specify ticksize after: ")) except Exception as e: print(e) else: with open(join(file_directory, "ticksize_changes.json"), "r") as f: ts_dict = json.load(f) print(ts_dict) # 先检查键是否存在 if symbol in ts_dict: ts_dict[symbol].append({'datetime': dt_string, 'ts_after': ts}) else: ts_dict[symbol] = [{'datetime': dt_string, 'ts_after': ts}] with open(join(file_directory, "ticksize_changes.json"), "w") as f: json.dump(ts_dict, f, default=str)
方案2:用dict.get()避免KeyError
get()方法在键不存在时返回None(可指定默认值),不会抛出异常:
# 替换if-else部分 if ts_dict.get(symbol): ts_dict[symbol].append({'datetime': dt_string, 'ts_after': ts}) else: ts_dict[symbol] = [{'datetime': dt_string, 'ts_after': ts}]
方案3:用dict.setdefault()简化逻辑
setdefault()会自动判断键是否存在:不存在则创建键并设置默认值,存在则返回对应值,一行代码完成追加或初始化:
# 替换整个if-else块 ts_dict.setdefault(symbol, []).append({'datetime': dt_string, 'ts_after': ts})
内容的提问来源于stack exchange,提问作者user11629
相关产品推荐
相关产品推荐

