Прежде всего, не очень ясно, какой вывод вам нужен, но исходя из предположения и описания, упомянутых в посте, кажется, что вы хотите отсортировать строковое поле не по целому значению, а по подстроке. .
Лучше использовать порядок для сортировки строк в алфавитном порядке.
@articles = Article.order(:title)
И это также будет служить цели, так как сначала будет соответствовать первому алфавиту каждой строки, а также одновременно обрабатывать нулевые значения.
Зачем писать собственную логику, если цель выполняется уже определенным методом.
Как насчет:
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])
Основываясь на ответе 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
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])
Я осуществил бы рефакторинг его как так:
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
функция, кажется, разбивает функциональность так, чтобы было легко видеть бизнес-логику, не увязая в коде повторной попытки.
Как 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