【问题标题】:Is it bad practice to use exceptions to assign variables?使用异常来分配变量是不好的做法吗?
【发布时间】:2015-05-31 04:26:21
【问题描述】:

使用以下内容本质上是不是不好的做法“如果dict和key存在,添加一个项目,如果不存在,先创建dict和key然后添加到它”?

附加问题:我是否必须在实例化时执行self.elements = {} 才能使第一个添加项起作用,还是它会使用第一个self.elements[elemType] = ... 即时创建它?

它在控制台中有效,但我确定我之前在此操作时遇到过错误。

try:
    self.elements[elemType][elemObj.id] = elemObj
except KeyError as _:
    self.elements[elemType] = {elemObj.id:elemObj}

【问题讨论】:

  • 不,这很好,但您通常不会在程序开始时创建一个空字典作为占位符吗?
  • 我认为这很好,但是您可能需要考虑使用 defaultdict 类来完全避免
  • 另外,如果您不打算使用Exception 实例,except KeyError: 也可以。
  • 这样做的问题是您最终可能会捕获并掩盖您没有预料到的关键错误。
  • 我认为 defaultdict 在这里不合适。元素字典只是在添加元素时从广播中接收元素,它们可以是 zwave 节点、android 相机等(这是一个家庭安全系统)——这个字典在我的 gui 中,旨在捕获通过添加到系统中的元素发布者广播并从中制作按钮以添加到 gui。我不想让它知道它可以接收什么类型,只是它可以接收它们。使用默认字典,我必须定义键和默认值,对吗?

标签: python exception dictionary exception-handling variable-assignment


【解决方案1】:

决定检查一下iftry 仍然运行得更快。

if.py

d = {}
for i in range(int(1e+6)):
    if i in d:
        d[i] += 1
    else:
        d[i] = 1

try.py

d = {}
for i in range(int(1e+6)):
    try:
        d[i] += 1
    except KeyError:
        d[i] = 1

if 的结果时间

$ time python if.py 

real    0m0.269s
user    0m0.224s
sys     0m0.044s

尝试的结果时间

$ time python try.py 

real    0m0.899s
user    0m0.858s
sys     0m0.040s

所以iftry 快三倍。

【讨论】:

    【解决方案2】:

    异常总是很慢。您可以分配值 - 通过使用 dict update。

    >>> foo = {1: {}}
    >>> foo[1].update({1: 2})
    >>> foo
    {1: {1: 2}}
    >>> foo[1].update({1: 3})
    >>> foo
    {1: {1: 3}}
    >>> foo[1].update({2: 4})
    >>> foo
    {1: {1: 3, 2: 4}}
    

    所以在你的情况下它看起来像

    self.elements[elemType].update({elemObj.id: elemObj})
    

    如果元素[elemType] 可能不存在,则更复杂

    self.elements.update({elemType: {elemObj.id: elemObj} })
    

    更新

    对于不覆盖 elemType - 可以检查它是否不存在。

    if elemType not in self.elements:
        self.elements[elemType] = {}
    self.elements[elemType].update({elemObj.id: elemObj})
    

    【讨论】:

    • 如果字典中没有 elemType 键,更新是否会抛出错误?我不希望字典知道它最终可能有什么键。
    • @您的编辑:如果 elemType 已经存在并且其中包含信息,因为这是要添加的“节点”类型的第 20 个项目,例如,它将覆盖该键中的所有内容一个新的定义,不是吗?不是只更新元素,而不是元素[elemType]中的字典吗?这越来越令人困惑。
    • 我认为它会归结为一个如果。这就是我在更新路径和创建 if 的那一刻得到的结果,SO 上的 pythonistas 开始在我的脑海中响起,“Python 不是 C,在 Python EAFP > LBYL 中,Python 中的异常很便宜,等等"
    猜你喜欢
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    相关资源
    最近更新 更多