我正在使用Python,每当我必须验证函数输入时,我认为输入有效,然后发现错误。
在我的情况下,我有一个普遍的Vector()
类,我用它做了一些不同的事情,其中一个是补充。它既可以作为Color()
类也可以作为Vector()
,因此当我向Color()
添加标量时,它应该将该常量添加到每个单独的组件中。 Vector()
和Vector()
添加需要按组件添加。
此代码用于光线跟踪器,因此任何速度提升都很棒。
以下是我的Vector()
课程的简化版本:
class Vector:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
try:
return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
except AttributeError:
return Vector(self.x + other, self.y + other, self.z + other)
我目前正在使用try...except
方法。有人知道更快的方法吗?
编辑:由于答案,我尝试并测试了以下解决方案,该解决方案在添加Vector()
对象之前专门检查了类名:
class Vector:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
if type(self) == type(other):
return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
else:
return Vector(self.x + other, self.y + other, self.z + other)
我使用timeit
对这两段代码进行了速度测试,结果非常重要:
1.0528049469 usec/pass for Try...Except
0.732456922531 usec/pass for If...Else
Ratio (first / second): 1.43736090753
我没有使用 no 输入验证对Vector()
类进行测试(即将检查结果移出类和实际代码),但我想它是甚至比if...else
方法更快。
延迟更新:回顾这段代码, 是最佳解决方案。
OOP使这更快:
class Vector:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y, self.z + other.z)
class Color(Vector):
def __add__(self, other):
if type(self) == type(other):
return Color(self.x + other.x, self.y + other.y, self.z + other.z)
else:
return Color(self.x + other, self.y + other, self.z + other)
答案 0 :(得分:80)
我赞成了Matt Joiner的回答,但是想要包括一些额外的观察结果,以明确说明,除了其他几个因素,在预检条件之间进行选择时, 4 次是重要的(称为LBYL或“在你跳跃之前看”)并且只处理异常(称为EAFP或“更容易请求宽恕而不是许可”)。
这些时间是:
其他因素包括:
最后一点是需要首先解决的问题:如果存在竞争条件的可能性,那么你别无选择,必须使用异常处理。一个典型的例子是:
if <dir does not exist>:
<create dir> # May still fail if another process creates the target dir
由于LBYL不排除异常就是这种情况,它没有提供真正的好处,也没有判断要求:EAFP是唯一能够正确处理竞争条件的方法。
但是,如果没有竞争条件,任何一种方法都是可行的。他们提供不同的权衡:
然后导致以下决定标准:
作为一个粗略的经验法则:
*在这种情况下,人们会根据他们“大多数时间”的考虑而有所不同。对我来说,如果我希望操作成功的时间超过一半,我会立即使用EAFP,直到我有理由怀疑这段代码是一个实际的性能瓶颈。
答案 1 :(得分:5)
在Python中,由于查找次数减少,异常通常更快。然而,一位朋友曾经说过(它应该适用于任何语言),假装每次发现异常时都会有一点延迟。避免在延迟可能成为问题的情况下使用例外情况。
在你给出的例子中,我会选择例外。