Вы, очевидно, хорошо ознакомились с классом sqlalchemy.orm.scoping.scoped_session
, и если вы посмотрите немного дальше в том же модуле, вы найдете следующий фрагмент (ссылка ) ):
def instrument(name):
def do(self, *args, **kwargs):
return getattr(self.registry(), name)(*args, **kwargs)
return do
for meth in Session.public_methods:
setattr(scoped_session, meth, instrument(meth))
Если мы рассмотрим это снизу вверх, мы сначала получим for meth in Session.public_methods:
l oop, где Session.public_methods
просто кортеж имен методов, предоставляемых Session
, и строка "query"
является одной из них:
class Session(_SessionClassMethods):
...
public_methods = (
...,
"query",
...,
)
Каждое из этих имен (meth
) в Session.public_methods
передается в setattr
вызов внутри l oop:
setattr(scoped_session, meth, instrument(meth))
Значение, которое присваивается имени метода в scoped_session
, является возвращаемым значением вызова instrument(meth)
, что закрытие называется do()
. Эта функция вызывает scoped_session.registry
, чтобы получить зарегистрированный объект Session
, получает именованный метод (meth
) и вызывает его с *args
& **kwargs
, которые были переданы do()
.
Поскольку for meth in Session.public_methods:
l oop определено в глобальном пространстве имен модуля, оно выполняется во время компиляции, прежде чем что-либо еще сможет использовать scoped_session
. Таким образом, к тому моменту, когда ваш код сможет овладеть экземпляром scoped_session
, эти методы уже были исправлены.