существует ли pythonic способ попробовать что-то до максимального количества раз?

Прежде всего, не очень ясно, какой вывод вам нужен, но исходя из предположения и описания, упомянутых в посте, кажется, что вы хотите отсортировать строковое поле не по целому значению, а по подстроке. .

Лучше использовать порядок для сортировки строк в алфавитном порядке.

@articles = Article.order(:title)

И это также будет служить цели, так как сначала будет соответствовать первому алфавиту каждой строки, а также одновременно обрабатывать нулевые значения.

Зачем писать собственную логику, если цель выполняется уже определенным методом.

77
задан Ben 15 July 2012 в 03:16
поделиться

5 ответов

Как насчет:

conn = MySQLdb.connect(host, user, password, database)
cursor = conn.cursor()
attempts = 0

while attempts < 3:
    try:
        cursor.execute(query)
        rows = cursor.fetchall()
        for row in rows:
            # do something with the data
        break
    except MySQLdb.Error, e:
        attempts += 1
        print "MySQL Error %d: %s" % (e.args[0], e.args[1])
86
ответ дан Dana 24 November 2019 в 10:50
поделиться

Основываясь на ответе Dana, Вы могли бы хотеть сделать это как декоратор:

def retry(howmany):
    def tryIt(func):
        def f():
            attempts = 0
            while attempts < howmany:
                try:
                    return func()
                except:
                    attempts += 1
        return f
    return tryIt

Затем...

@retry(5)
def the_db_func():
    # [...]

Расширенная версия, которая использует decorator модуль

import decorator, time

def retry(howmany, *exception_types, **kwargs):
    timeout = kwargs.get('timeout', 0.0) # seconds
    @decorator.decorator
    def tryIt(func, *fargs, **fkwargs):
        for _ in xrange(howmany):
            try: return func(*fargs, **fkwargs)
            except exception_types or Exception:
                if timeout is not None: time.sleep(timeout)
    return tryIt

Затем...

@retry(5, MySQLdb.Error, timeout=0.5)
def the_db_func():
    # [...]

Для установки decorator модуль :

$ easy_install decorator
76
ответ дан habnabit 24 November 2019 в 10:50
поделиться
conn = MySQLdb.connect(host, user, password, database)
cursor = conn.cursor()

for i in range(3):
    try:
        cursor.execute(query)
        rows = cursor.fetchall()
        for row in rows:
            # do something with the data
        break
    except MySQLdb.Error, e:
        print "MySQL Error %d: %s" % (e.args[0], e.args[1])
7
ответ дан webjunkie 24 November 2019 в 10:50
поделиться

Я осуществил бы рефакторинг его как так:

def callee(cursor):
    cursor.execute(query)
    rows = cursor.fetchall()
    for row in rows:
        # do something with the data

def caller(attempt_count=3, wait_interval=20):
    """:param wait_interval: In seconds."""
    conn = MySQLdb.connect(host, user, password, database)
    cursor = conn.cursor()
    for attempt_number in range(attempt_count):
        try:
            callee(cursor)
        except MySQLdb.Error, e:
            logging.warn("MySQL Error %d: %s", e.args[0], e.args[1])
            time.sleep(wait_interval)
        else:
            break

Факторизация эти callee функция, кажется, разбивает функциональность так, чтобы было легко видеть бизнес-логику, не увязая в коде повторной попытки.

6
ответ дан cdleary 24 November 2019 в 10:50
поделиться

Как S.Lott, мне нравится, когда флаг проверяет, сделаны ли мы:

conn = MySQLdb.connect(host, user, password, database)
cursor = conn.cursor()

success = False
attempts = 0

while attempts < 3 and not success:
    try:
        cursor.execute(query)
        rows = cursor.fetchall()
        for row in rows:
            # do something with the data
        success = True 
    except MySQLdb.Error, e:
        print "MySQL Error %d: %s" % (e.args[0], e.args[1])
        attempts += 1
6
ответ дан Kiv 24 November 2019 в 10:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: