Форум сайта python.su
Писать на Python-e я уже научился а творить еще нет (((
Тут недавно на глаза попался код (немного упрощен ) :
import sys
import sqlite3
# Обертка для базы данных
class Database:
# Класс-обертка для соединения,
# чтобы использовать с with
class dbConnection:
def __init__(self, dbfile):
self.dbfile = dbfile
def __enter__(self):
self.connection = sqlite3.connect(self.dbfile)
self.connection.row_factory = sqlite3.Row
return self.connection
def __exit__(self, type, value, traceback):
if traceback is None:
self.connection.commit()
self.connection.close()
else:
self.connection.rollback()
self.connection.close()
self.connection = None
def __init__(self, dbfile='./users.db'):
# Создание таблицы при первом запуске
newdb = 1 if not os.path.isfile(dbfile) else 0
if newdb:
try:
with self.dbConnection(dbfile) as connection:
connection.execute("""CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
jid TEXT UNIQUE NOT NULL,
token TEXT NOT NULL,
shard TEXT NOT NULL
)""")
except:
raise DatabaseError
self.dbfile = dbfile
def user(self, jid):
try:
with self.dbConnection(self.dbfile) as connection:
res = connection.execute('SELECT * FROM `users` WHERE `jid`=?',
(jid,)).fetchone()
return res
except:
raise DatabaseError
def updateUser(self, jid, token="", shard=""):
try:
with self.dbConnection(self.dbfile) as connection:
connection.execute("""REPLACE INTO users
(jid, token, shard)
VALUES
(?, ?, ?)""",
(jid, token, shard))
except:
raise DatabaseError
def delUser(self, jid):
try:
with self.dbConnection(self.dbfile) as connection:
connection.execute("DELETE FROM `users` WHERE `jid` = ?",
(jid,))
except:
raise DatabaseError
langpack = {
' dbError ': "error DB"
}
storage = Database()
# Классы для исключений:
# raise BasicError - стандартное значение,
# raise BasicError('Error!') - заданное.
class BasicError(Exception):
default = ''
def __init__(self, value=None):
self.value = self.default if not value else value
def __str__(self):
return self.value
class DatabaseError(BasicError):
default = Database.langpack['dbError']
while 1:
try:
x = int(raw_input("Введите число ")) #Здесь может возникнуть исключение
break #Если всё правильно, то выходим из бесконечного while
except ValueError: #А вот здесь обрабатывается исключение неверного формата числа
print ''Ой-ой. Неправильное число. Попробуйте снова..."
try:
with self.dbConnection(dbfile) as connection:
connection.execute("""CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
jid TEXT UNIQUE NOT NULL,
token TEXT NOT NULL,
shard TEXT NOT NULL
)""")
except:
raise DatabaseError
Офлайн
Во-первых, никогда не перехватывай все исключения скопом. Т.е. приведённый тобой код хоть и работает, но не корректен.
Во-вторых, обрати внимание на то, что райзится своё исключение. Оно вполне может перехватываться где-то уровнем выше. Там, где требуется перехватить только это исключение и никакое другое, вроде ошибки базы данных в запросе после создания. Как пример:
class DatabaseError(RuntimeError): pass
def init(self):
try:
with self.dbConnection(dbfile) as connection:
connection.execute("""CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
jid TEXT UNIQUE NOT NULL,
token TEXT NOT NULL,
shard TEXT NOT NULL
)""")
except sqlite3.DatabaseError as exc:
raise DatabaseError
try:
init(self)
with self.dbConnection(dbfile) as conn:
conn.execute(u'''Какой-то странный запрос, однако... Не работает и ругается страшно...''')
except DatabaseError:
print u'Однако Error... Но тут можно оленя поймать, однако...'
Офлайн
ZZZА смысл ловить sqlite3.DatabaseError в __init__? Для этого примера обработка любого исключения (sqlite3.DatabaseError) в конструкторе будет выглядеть так:
Во-первых, никогда не перехватывай все исключения скопом. Т.е. приведённый тобой код хоть и работает, но не корректен.
Во-вторых, обрати внимание на то, что райзится своё исключение. Оно вполне может перехватываться где-то уровнем выше. Там, где требуется перехватить только это исключение и никакое другое, вроде ошибки базы данных в запросе после создания. Как пример:
Print “……. Error …….”
os._exit(0)
try:
init(self)
with self.dbConnection(dbfile) as conn:
conn.execute(u'''Какой-то странный запрос, однако... Не работает и ругается страшно...''')
except DatabaseError:
print u'Однако Error... Но тут можно оленя поймать, однако...'
Офлайн
В любом случае ловить все исключения это ошибочное решение.
Что же касается, ловить или нет: обычно работает правило - обрабатывай исключение там, где ты можешь его обработать.
В данном же случае (__init__) можешь не перехватывать, если устроит просто падение со стандартным икспшном. Или обработай и аварийно завершись, если ничего не можешь сделать.
Если же отвечать на философский вопрос - зачем это делать вообще, то далеко не все приложения завершаются, не обнаружив БД. К примеру, некоторые могут вывести в гуй диалог и попросить пользователя скорректировать адрес/имя БДю
Отредактировано (Авг. 8, 2009 10:25:17)
Офлайн
ozssssЧтобы сгенерировать своё исключение, Которое мы отлавливаем уровнем выше.
А смысл ловить sqlite3.DatabaseError в __init__?
def init(self):
with self.dbConnection(dbfile) as connection:
connection.execute("""CREATE TABLE ...)""")
try:
init(self)
except sqlite3.DatabaseError:
print u'Однако Error... Но тут можно оленя поймать, однако...'
else:
with self.dbConnection(dbfile) as conn:
conn.execute(u'''Какой-то странный запрос, однако... Не работает и ругается страшно...''')
Офлайн