Я нашел ниже в Интернете, однако из моего небольшого воздействия на Python я знаю, что можно привязывать функции к объекту на мухе. Я также знаю, что все в Python является объектом. Я еще не понимаю, чего можно достичь с помощью нижеизложенного и его прецедента. Это та часть, в которой мне нужна помощь:
run_sql_command.c = c
def get_sql_object(c):
def run_sql_command(command, arguments=[]):
c.execute(command, arguments)
return c.fetchall()
run_sql_command.c = c
return run_sql_command
Эта строка добавляет атрибут c
функции run_sql_command
, передавая ей значение, переданное функции get_sql_object()
, предположительно, курсором базы данных. Вы, наверное, уже так много знали.
При ограниченном объеме этого фрагмента утверждение не имеет смысла. В более широком контексте курсор может быть повторно использован в другом месте кода. Ищите доступ к атрибуту .c
в других частях кода и посмотрите, что с ним сделано.
Идея здесь (я считаю) заключается в том, что кто-то создает объект-заполнитель, который ссылается на курсор c
чтобы впоследствии его можно было использовать для выполнения запросов. Предполагаемое использование, вероятно, примерно так:
c = DBConnectionObject.cursor()
myExecutor = get_sql_object(c)
# some amount of code later
rows = myExecutor(Queries.GetAllUsersByFName, ['Larry', 'Bob'])
- Чтобы ответить на некоторые из комментариев -
Я считаю, что попытка сохранить курсоры вокруг может вызвать проблемы в энергозависимых средах, где не всегда гарантируется, что соединение с базой данных остается подключенным. Вместо этого я выбираю этот подход:
class DBConnection(object):
def __init__(self, dbpath):
self.dbPath = dbpath
# Any connection object here, really.
self._conn = kinterbasdb.connect()
def cursor(self, query, params = None):
try:
cursor = self._conn.cursor()
if params:
cursor.execute(query, params)
else:
cursor.execute(query)
return cursor
except (kdb.ProgrammingError, AttributeError), e:
print e
def qry(self, query, params = None):
cursor = self.cursor(query, params)
return [[x[0].title() for x in cursor.description]] + [r for r in cursor.fetchall()]
Затем вы должны создать глобальное соединение с базой данных следующим образом:
dbcon = DBConnection('/path/to/mydb.fdb')
и запускать запросы с помощью:
rows = dbcon.qry(Queries.GetSomething)
или:
filtered = dbcon.qry(Queries.FilteredQuery, ['my', 'parameters'])
Я пропустил некоторые из кода, который обрабатывает/восстанавливает обработку ошибок в базе данных, если соединение опустилось, но общая идея есть. Таким образом, курсоры создаются, когда они необходимы, используются и позволяют выйти из области видимости, что позволяет централизовать обработку ошибок.
Я думаю, что run_sql_command.c
существует, чтобы сохранить доступную ссылку на c, например, чтобы закрыть ее позже.
run_sql_command.c = c
. Возможно, автор кода не понимал, что c все еще будет доступен внутренней функции.