我有两个表达方式。我需要尝试一个表达式,如果它引发异常,请尝试另一个表达式,但如果第二个也引发异常 - 引发异常。
我试过这个,但它看起来很难看,我不确定这是解决这个问题的最佳方法:
try:
image = self.images.order_by(func.random()).limit(1)
except:
try:
image = self.images.order_by(func.rand()).limit(1)
except ProgrammingError:
raise ProgrammingError(
'The database engine must be PostgtreSQL or MySQL')
你是怎么做到的?
答案 0 :(得分:3)
使用循环:
for methname in ("random", "rand"):
try:
image = self.images.order_by(getattr(func, methname)()).limit(1)
break
except ProgrammingError:
continue
else:
raise ProgrammingError("The database engine must be PostgtreSQL or MySQL")
仅当循环正常终止(即没有else
)时才执行循环的break
子句,这就是我们在break
赋值后image
的原因。如果您认为这太棘手了,因为else
子句很少与for
一起使用,那么这也可行:
image = None
for methname in ("random", "rand"):
try:
image = self.images.order_by(getattr(func, methname)()).limit(1)
except ProgrammingError:
continue
if not image:
raise ProgrammingError("The database engine must be PostgtreSQL or MySQL")
答案 1 :(得分:3)
制作单独的功能非常有用。
def get_random_image(self):
for rand in func.random, func.rand:
try:
return self.images.order_by(rand()).limit(1)
except ProgrammingError:
pass
raise ProgrammingError('This database engine is not supported')
答案 2 :(得分:2)
在这种特殊情况下,我实际上是在选择函数之前尝试检测数据库。你能从你的代码到达数据库连接吗?如果是这样,只需打开drivername:
random = None
if drivername == 'postgres':
random = func.random
elif drivername == 'mysql':
random = func.rand
else:
raise ValueError('This module requires that you use PostgreSQL or MySQL')
然后,在选择图像时,请使用random
值:
image = self.images.order_by(random()).limit(1)
答案 3 :(得分:0)
实际上它可能是一个设计缺陷。提出异常是对通常不会发生的事件采取行动。如果你想在函数上做一些事情(除了处理异常),看起来你想要尝试的第一个语句不是一个应该得到异常的语句。
所以而不是:
try:
do statement 1
except ...
try:
do statement 2
except:
想一想:
if (statement_1 result == ...)
try:
do statement 2
except:
答案 4 :(得分:0)
如果你想检查rand或random是否是一个类的函数,你也可以使用
if 'rand' in dir(some object of a class)