如果 a.) 密钥不存在或 b.) 密钥未经过验证,则以最惯用的方式安全地从 dict() 中弹出密钥

Mic*_*rts 2 python dictionary idioms

所以,我想知道。我遇到以下问题,即在对弹出的值执行某些操作之前,字典弹出需要进行多次检查和平衡。

\n\n

我知道:

\n\n
    \n
  1. 如果字典中存在键,则从dict.pop()字典中删除具有给定键的元素并返回其值。

  2. \n
  3. 如果给定的键在字典中不存在\xe2\x80\x99t,则返回给定的默认值。

  4. \n
  5. 如果给定的键在字典中不存在\xe2\x80\x99并且没有默认值传递给pop(),那么它将抛出KeyError。

  6. \n
\n\n

所以,我觉得3.我需要首先处理KeyError异常。如果是,则从字典中弹出该键。

\n\n

然后,2如果返回默认值,则不执行任何操作。

\n\n

然后,如果为 1,则执行一些验证,因为该值需要匹配预定义的字符串格式(电子邮件的正则表达式匹配,使用 Django 的内置from django.core.validators import email_re,如果细节很重要)。

\n\n

我们有以下内容:

\n\n
\ndef some_function():\n        try:\n            email = account.pop(\'email\', None)\n        except KeyError as ex:\n            return\n\n        if not email:\n            return\n\n        if not email_re.match(email):\n            return\n\n        # Get/Update Or Create SurfAccount:\n        surf_account, created = SurfAccount.objects.update_or_create(\n            email=email,\n            defaults=account\n        )\n\n        return surf_account, surfer\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,我不确定这是与 KeyError 异常处理程序结合执行验证的最惯用的方法...因为如果我们这样调用函数,我们可能会遇到 TypeError:

\n\n
surf_account, surfer = some_function()\n
Run Code Online (Sandbox Code Playgroud)\n\n

returning因为当验证失败时我们就“退出”了......

\n\n

问:)那么,执行此类字典弹出验证的最惯用方法是什么?

\n

Mas*_*inn 7

dict.pop(key, default)永远不会引发KeyError,如果键不存在,它只会返回默认值。所以你的 try: except: 没有用。

除此之外,以这种方式使用 pop 是很好的,特别是如果您预计这种情况很常见的话。

第二个注释的问题是函数的调用约定不一致,有时返回两个结果,有时不返回任何结果,因此很难使用。

  • 常见的Python习惯会建议你的函数在电子邮件无效(无论是丢失还是不正确)的情况下引发异常,这样“快乐路径”总是返回两个值,而“不快乐路径”是一个异常处理程序,只需替换你的return通过提出适当的例外来裸露
  • 如果您不想出于某种原因引发异常,那么您需要将结果更改为始终为单个值(例如数据类),或者您需要更改错误情况以返回类似的内容None, None(这本身就是以与当前问题不同的方式有些风险,因为if some_function()总会过去)。