Python -“请求原谅而不是允许”-解释

发布于 2021-02-02 23:20:43

我并不是要求个人对这一哲学有“宗教”的看法,而是一些更专业的观点。 我理解这句话是几个试金石之一,看看你的代码是否是“pythonic”。但对我来说,pythonic意味着干净、简单和直观,没有为错误的代码加载异常处理程序。 所以,实际的例子。我定义一个类:

class foo(object):
    bar = None

    def __init__(self):
        # a million lines of code
        self.bar = "Spike is my favorite vampire."
        # a million more lines of code

现在,从程序背景来看,在另一个函数中,我想这样做:

if foo.bar:
    # do stuff

如果我不耐烦并且没有执行初始foo=None,我将得到一个属性异常。所以,“请求原谅而不是允许”建议我应该这样做?

try:
    if foo.bar:
        # do stuff
except:
    # this runs because my other code was sloppy?

为什么我最好在try块中添加额外的逻辑,这样我就可以使类定义更加模糊?为什么不先定义所有内容,然后再明确授予权限?
(不要因为使用try/except块而责怪我。。。我到处都用。我只是觉得用它们来捕捉我自己的错误是不对的,因为我不是一个彻底的程序员。)

关注者
0
被浏览
338
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    经典的“请求宽恕而不是允许”示例是从dict可能不存在的a 中访问值。例如:

    names = { 'joe': 'Joe Nathan', 'jo': 'Jo Mama', 'joy': 'Joy Full' }
    name = 'hikaru'
    
    try:
        print names[name]
    except KeyError:
        print "Sorry, don't know this '{}' person".format(name)
    

    在此说明了可能发生的异常(KeyError),因此你并不是在请求所有可能发生的错误的宽恕,而只是要求自然发生的错误。为了进行比较,“先问权限”方法可能类似于:

    if name in names:
        print names[name]
    else:
        print "Sorry, don't know this '{}' person".format(name)
    要么
    
    real_name = names.get(name, None)
    if real_name:
        print real_name
    else:
        print "Sorry, don't know this '{}' person".format(name)
    

    这样的“请求宽恕”的例子通常太简单了。IMO尚不十分清楚try/ except块本质上优于if/ else。当执行可能以各种方式失败的操作时,例如解析,操作,操作,操作等,真正的价值要清晰得多。使用eval(); 访问操作系统,中间件,数据库或网络资源;或执行复杂的数学。当存在多种潜在的故障模式时,为获得原谅做好准备非常有价值。

    有关代码示例的其他说明:

    你无需在每个变量用法周围都进行浇注try/ except阻止。那太可怕了。而且你不需要设置self.bar,__init__()因为它已在class上面的定义中设置。通常在类中定义它(如果它的数据很可能在该类的所有实例之间共享)或在中定义__init__()(如果它是实例数据,特定于每个实例)。

    None顺便说一下,值并非是未定义的或错误。这是一个特定且合法的值,表示无,无,空或无。许多语言都有这样的值,因此程序员不会“重载” 0,“ -1,''(空字符串)或类似的有用值。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看