对于令人困惑的标题感到抱歉。
我最近在我的项目中开始这样做,我想知道它是否更有效率,以及它是否是一种可怕的练习方式。
以下是数据库界面的示例:
def register(self, user, pw):
"""Register user/pw into the database"""
if self.isStarted():
raise Exceptions.Started
hashed = hashlib.sha512(pw).hexdigest()
self._db_cur.execute('''INSERT INTO PLAYERS (name, password)
values (?, ?)''', [user, hashed])
self._db.commit()
我在这里提出异常,但我已经在其他地方做了回复。
我觉得这允许false-cases退出顶部的函数,而不是继续执行函数,看看是否还有更多的代码供它们运行。
我很少在代码中看到这一点:这是一个不好的做法,还是不会像我想象的那样产生任何性能?
为了帮助澄清,我习惯的是:
if (somethingTrue):
runThis()
thisToo()
x = andThis()
return x
return None
以及我已经开始做的事情,而且我很开心:
if (!somethingTrue):
return None
runThis()
thisToo()
x = andThis()
return x
后者似乎给人的印象(特别是在超过4行的函数中)代码不是条件的一部分,当它是这样的时候。这也使它看起来更好,同时坚持PEP-8,所以我真的对它有所了解。
我有一种感觉,这打破了一些非常神圣的东西。这是好的还是亵渎神灵?
答案 0 :(得分:5)
问题的一部分是关于风格和最佳实践 - 因此恕我直言不是'正确'的方式。
在我看来,嵌套版本(没有直接返回)来自'历史'编程语言,如'C',其中整个清理在正确的地方完成一次。人工示例仅显示要点:
int f() {
int result = 1;
char * buffer = (char *)malloc(77);
if(buffer!=NULL) {
int const fd = open("/tmp/data.log", O_RDONLY);
if(fd!=-1) {
ssize_t const read_cnt = read(fd, buffer, 77);
if(read_cnt!=77) {
/* Do something: was not possible to read 77 bytes. */
result = 0;
}
close(fd);
}
free(buffer);
}
return result;
}
从其他行返回到最后一行是不正确的 - 因为那时可能会有资源泄漏。
当只使用在析构函数中完全销毁的对象时 - 或者当不需要清理资源时(因为没有分配),我更喜欢'短'路径返回。这使得事情变得更加清晰:如果函数的前提条件不满足,则无法“真正”执行函数体。另外:你不需要那么多的缩进,它更容易阅读。
表现:我做了一些测试;我无法衡量两种方式之间的差异。恕我直言,如果您需要调整此级别的性能,您可能需要考虑选择其他编程语言。 ; - )
答案 1 :(得分:4)
如果您必须进行检查(为了正确),那么我认为在顶部进行检查是个好主意。
在某些情况下,您可以选择(1)进行检查以避免不必要的工作,或者(2)只是跳过检查并始终进行工作。在这种情况下,你可以考虑跳过支票,如果你认为不做工作的情况会非常罕见,以至于额外支票的费用会比不时做不必要的工作花费更多(如果你真的想确定)。然后,可能不清楚是哪种情况;然后我会说一个简单的if语句非常便宜(假设支票本身并不昂贵),所以只需要检查并且不要太担心,除非你看到性能问题。您可以随时进行分析。
修改:根据您的进一步示例,您可能会想到一个不同的问题。关于这个问题,我会说你通常应该先用最短的代码放一个案例,所以你没有像
这样的东西。if positive_case:
lots of stuff
lots more stuff
...
else:
whatever this corresponds to is now off the screen
您的技术也是避免过多嵌套的常用方法。退出if
,然后省略else
,就可以展平
if error:
raise exception
else:
do more stuff
if error:
...
到
if error:
raise exception
do more stuff
if error:
...
我想你提到的是,PEP-8实际上提到并推荐了这种技术。我不确定你为什么觉得这可能是亵渎神灵的。许多事情只是个人偏好,无论是利弊还是利弊,你都有权对这些权衡做出自己的看法。