一尘不染

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

python

我并不是要求个人对这一哲学有“宗教”的看法,而是一些更专业的观点。 我理解这句话是几个试金石之一,看看你的代码是否是“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块而责怪我。。。我到处都用。我只是觉得用它们来捕捉我自己的错误是不对的,因为我不是一个彻底的程序员。)


阅读 718

收藏
2020-02-13

共1个答案

一尘不染

经典的“请求宽恕而不是允许”示例是从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,''(空字符串)或类似的有用值。

2020-02-13