Python 中嵌套的 try/except 块是一种好的编程习惯吗?

新手上路,请多包涵

我正在编写自己的容器,它需要通过属性调用来访问内部字典。容器的典型用法是这样的:

 dict_container = DictContainer()
dict_container['foo'] = bar
...
print dict_container.foo

我知道写这样的东西可能很愚蠢,但这是我需要提供的功能。我正在考虑通过以下方式实现这一点:

 def __getattribute__(self, item):
    try:
        return object.__getattribute__(item)
    except AttributeError:
        try:
            return self.dict[item]
        except KeyError:
            print "The object doesn't have such attribute"

我不确定嵌套的 try/except 块是否是一个好习惯,所以另一种方法是使用 hasattr()has_key()

 def __getattribute__(self, item):
        if hasattr(self, item):
            return object.__getattribute__(item)
        else:
            if self.dict.has_key(item):
                return self.dict[item]
            else:
                raise AttributeError("some customised error")

或者像这样使用其中之一和一个 try catch 块:

 def __getattribute__(self, item):
    if hasattr(self, item):
        return object.__getattribute__(item)
    else:
        try:
            return self.dict[item]
        except KeyError:
            raise AttributeError("some customised error")

哪个选项最 Pythonic 和优雅?

原文由 Michal 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 379
2 个回答

你的第一个例子非常好。甚至官方 Python 文档也推荐这种称为 EAFP 的风格。

就个人而言,我更愿意在不必要时避免嵌套:

 def __getattribute__(self, item):
    try:
        return object.__getattribute__(item)
    except AttributeError:
        pass  # Fallback to dict
    try:
        return self.dict[item]
    except KeyError:
        raise AttributeError("The object doesn't have such attribute") from None

附言。 has_key() 在 Python 2 中已经弃用了很长时间。使用 item in self.dict 代替。

原文由 lqc 发布,翻译遵循 CC BY-SA 4.0 许可协议

虽然在 Java 中使用异常进行流控制确实是一种不好的做法(主要是因为异常会强制 JVM 收集资源( 更多信息)),但在 Python 中你有两个重要的原则: duck typingEAFP 。这基本上意味着鼓励您尝试按照您认为的方式使用对象,并在事情不是这样的时候处理。

总之,唯一的问题是您的代码缩进太多。如果您愿意,请尝试简化一些嵌套,例如上面建议 的答案中建议的 lqc

原文由 Bruno Penteado 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题