首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中嵌套的try/except块是一种很好的编程实践吗?

Python中嵌套的try/except块是一种很好的编程实践吗?
EN

Stack Overflow用户
提问于 2013-06-10 07:37:30
回答 9查看 238.8K关注 0票数 255

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

代码语言:javascript
复制
dict_container = DictContainer()
dict_container['foo'] = bar
...
print dict_container.foo

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

代码语言:javascript
复制
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()

代码语言:javascript
复制
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块,如下所示:

代码语言:javascript
复制
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风格和优雅的?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2013-06-10 07:46:45

您的第一个示例完全正确。即使是官方的Python文档也推荐这种称为EAFP的样式。

就我个人而言,我更喜欢在不必要的时候避免嵌套:

代码语言:javascript
复制
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

PS。has_key()在Python2中已经被弃用了很长一段时间,请改用item in self.dict

票数 225
EN

Stack Overflow用户

发布于 2013-06-10 07:46:12

虽然在Java语言中使用异常进行流控制确实是一种糟糕的做法(主要是因为异常迫使虚拟机收集资源(more here)),但在Python语言中有两个重要的原则:duck typingEAFP。这基本上意味着鼓励您尝试以您认为的方式使用对象,并在事情不是这样时进行处理。

总而言之,唯一的问题是你的代码缩进太多了。如果你喜欢,试着简化一些嵌套,就像lqcthe suggested answer above中建议的那样。

票数 20
EN

Stack Overflow用户

发布于 2013-06-10 07:46:00

对于您的特定示例,您实际上不需要嵌套它们。如果try块中的表达式成功,则函数将返回,因此,只有在第一次尝试失败时,才会运行整个try/except块之后的所有代码。所以你可以这样做:

代码语言:javascript
复制
def __getattribute__(self, item):
    try:
        return object.__getattribute__(item)
    except AttributeError:
        pass
    # execution only reaches here when try block raised AttributeError
    try:
        return self.dict[item]
    except KeyError:
        print "The object doesn't have such attribute"

嵌套它们并不坏,但我觉得让它保持扁平会使结构更清晰:您将按顺序尝试一系列内容,然后返回第一个有效的内容。

顺便说一句,您可能需要考虑是否真的希望在这里使用__getattribute__而不是__getattr__。使用__getattr__将会简化事情,因为您将知道正常的属性查找过程已经失败。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17015230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档