Python中检查字典字段是否存在的正确方式?hasattr用法疑问
geolocation字段的问题分析与修正 我正在调用API,返回的数据示例如下:
{"id": "17", "address": "Av. Nossa Senhora de Copacabana", "addressComplement": "A", "number": "945", "cityId": "2", "cityName": "Rio de Janeiro", "state": "Rio de Janeiro", "uf": "RJ", "neighborhood": "Copacabana", "properties": {}, "telephones": [], "geolocation": { "lat": -22.97625, "lng": -43.19002 }}但部分记录不含
geolocation字段,需在代码中检查该字段是否存在。我尝试使用hasattr实现,代码片段如下:if hasattr(i, 'geolocation'): address_lat = i['geolocation']['lat'] address_lng = i['geolocation']['lng'] else: address_lat = 0.0 address_lng = 0.0我的思路是检查索引
i对应的位置是否存在geolocation字段,存在则进入条件分支赋值,否则将变量设为0.0。请问我是否操作有误?这是hasattr的正确用法吗?
你的操作确实有误,hasattr()并不是用来检查字典中是否存在键的正确方法。
为什么hasattr在这里不适用?
hasattr(object, name)的作用是检查一个Python对象(比如类的实例)是否拥有指定名称的属性,比如你定义了一个User类,实例化后可以用hasattr(user, 'name')来判断这个用户对象有没有name属性。
但你这里的i是API返回的JSON转换后的字典,字典的"键"和对象的"属性"是完全不同的概念——哪怕字典里有geolocation这个键,hasattr(i, 'geolocation')也会返回False,因为字典对象本身并没有名为geolocation的属性。
正确的几种实现方式
1. 用in操作符直接检查键存在性
这是最直观的方式,专门用来判断字典是否包含某个键:
if 'geolocation' in i: address_lat = i['geolocation']['lat'] address_lng = i['geolocation']['lng'] else: address_lat = 0.0 address_lng = 0.0
2. 用字典的get()方法(更简洁鲁棒)
get()方法支持指定键不存在时的默认值,还能嵌套处理,同时覆盖geolocation存在但缺少lat/lng的情况:
geolocation = i.get('geolocation', {}) address_lat = geolocation.get('lat', 0.0) address_lng = geolocation.get('lng', 0.0)
这种写法容错性更强,哪怕geolocation是个空字典,也不会抛出异常。
3. 异常捕获(Python风格的EAFP写法)
Python推崇"请求原谅比预先许可更容易"的思路,直接尝试取值,捕获可能的KeyError:
try: address_lat = i['geolocation']['lat'] address_lng = i['geolocation']['lng'] except KeyError: address_lat = 0.0 address_lng = 0.0
如果你的API返回的大部分数据都包含geolocation字段,这种写法的效率会更高。
总的来说,你核心的问题是混淆了字典的键和对象的属性,把字典当成类实例来处理了。换成上面任意一种方法,都能正确实现你想要的逻辑。
内容的提问来源于stack exchange,提问作者random2137

