Python断断续续地抛出;属性错误:';非类型';对象没有属性';获取'&引用;在同一本字典上

Python断断续续地抛出;属性错误:';非类型';对象没有属性';获取'&引用;在同一本字典上,python,dictionary,Python,Dictionary,我有一个嵌套字典,如下所示: mail = { 'data': { 'from': {'text': '123@example.com'}} # some other entries... } 我正在尝试使用以下代码从值复制: data = mail.get('data') new_dict['parse']['from'] = data.get('from').get('text') 第二行抛出异常: AttributeError:'NoneType'对象没有属性'get'

我有一个嵌套字典,如下所示:

mail = {
   'data': { 'from': {'text': '123@example.com'}}
    # some other entries...
}
我正在尝试使用以下代码从值复制

data = mail.get('data')
new_dict['parse']['from'] = data.get('from').get('text')
第二行抛出异常:

AttributeError:'NoneType'对象没有属性'get'

奇怪的是,这只会偶尔发生。如果我在第二行前面添加一条打印语句,如:

data = mail.get('data')
print(type(data.get('from')))
new_dict['parse']['from'] = data.get('from').get('text')
错误消失,我得到了预期的
。如果删除print语句,它有时会工作,有时会抛出错误。代码或数据中没有其他更改。我使用
get()
的原因是为了在键丢失的情况下安全地检索值。

在调用
data.get('from').get('text')
中,如果
数据
不包含键
'from'
,它将返回
None.get('text')
引发您看到的异常,因为
None
对象没有
get
方法(当然)

解决方法是传入一个比
None
(默认对象)更好的默认对象,后者具有
get
方法。那将是一本空字典,
{}

data = mail.get('data')
new_dict['parse']['from'] = data.get('from', {}).get('text')

在这种情况下,使用
get
并不比使用括号表示法更安全,因为您没有指定要使用的默认值。使用此示例
mail
对象的此代码不会失败,因此我们无法帮助您。但是
中的键
存在。。。正如我提到的,你在
mail
中看到的字典实际上就是我传递的东西。不过,感谢您提出的改进建议。@swdon显然有时候不是,而且当您插入
print
语句时,您还没有幸运地捕捉到其中一个实例。@swdon“但是来自那里的键”=>如果Python告诉您它不是,那么它不是,句号。@swdon没有看到您的解释器,我们不知道。我们所知道的是,
mail.get('data')
返回的对象有时是一个字典(因为它有
get
方法,否则您将不得不执行
mail.get('data',{})
)操作,但它没有来自
的键。这是极不可能的(例如,几乎不可思议地不可能)Python错误地读取了内存,而且问题很可能是产生
邮件
字典的任何东西中的更高级问题。@Graipher另一个可能的原因是代码的另一部分从dict中删除了密钥。相当多的人盲目地认为传递赋值或参数会创建副本在这里发帖,想知道为什么有些物体在你声称他们没有碰它的时候会发生变化。。。