7

我有两种表达方式。我需要尝试一个表达式,如果它引发异常,请尝试另一个,但如果第二个也引发异常 - 引发异常。

我试过这个,但它看起来很难看,我不确定这是解决这个问题的最佳方法:

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')

你怎么做呢?

4

5 回答 5

5

使用循环:

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只有当循环正常终止(即没有 a )时才会执行循环的子句,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")
于 2012-08-13T14:32:17.183 回答
5

制作一个单独的函数非常有帮助。

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')
于 2012-08-13T14:42:00.027 回答
2

在这种特殊情况下,我实际上会在选择函数之前尝试检测数据库。你能从你的代码中访问数据库连接吗?如果是这样,只需打开驱动程序名称:

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)
于 2012-08-13T14:35:39.623 回答
0

实际上它可能是一个设计缺陷。引发异常是对通常不应该发生的事件采取行动。如果你想在一个异常中做一些功能性的事情(除了处理异常),看起来你想尝试的第一个语句根本不是应该得到异常的语句。

所以而不是:

try:
    do statement 1
except ...
    try:
        do statement 2
    except:

想一想 :

if (statement_1 result == ...)
    try:
         do statement 2
    except:
于 2012-08-13T14:33:02.807 回答
0

如果你想检查 rand 或 random 是否是一个类的函数,你也可以使用

if 'rand' in dir(some object of a class)
于 2012-08-13T14:40:44.753 回答