我们发现Session与scoped_session都有一些方法:

但是scoped_session的源码里面没有设置这些方法让我们从源码里去窥探下源码在哪里设置了这些方法:

Session里面的方法放在了public_methods里面:

scoped_session的源码里面没有这些方法?:

那它怎么实现这些方法的呢?

我们看到了它的构造方法:

 def __init__(self, session_factory, scopefunc=None):
"""Construct a new :class:`.scoped_session`. :param session_factory: a factory to create new :class:`.Session`
instances. This is usually, but not necessarily, an instance
of :class:`.sessionmaker`.
:param scopefunc: optional function which defines
the current scope. If not passed, the :class:`.scoped_session`
object assumes "thread-local" scope, and will use
a Python ``threading.local()`` in order to maintain the current
:class:`.Session`. If passed, the function should return
a hashable token; this token will be used as the key in a
dictionary in order to store and retrieve the current
:class:`.Session`. """
self.session_factory = session_factory if scopefunc:
self.registry = ScopedRegistry(session_factory, scopefunc)
else:
self.registry = ThreadLocalRegistry(session_factory)

第一次进来时,scopefunc是空的。

走else,

 self.registry = ThreadLocalRegistry(session_factory)
就会实例化:ThreadLocalRegistry。
class ThreadLocalRegistry(ScopedRegistry):
"""A :class:`.ScopedRegistry` that uses a ``threading.local()``
variable for storage. """ def __init__(self, createfunc):
self.createfunc = createfunc
self.registry = threading.local()

里面有两个对象  self.createfunc和registry:

registry是唯一标识,

session加上括号就会执行__call__方法:

因为self.registry.value第一次进入没有值:

所以走except  就是执行self.createfunc()往前找传的值是session_factory那么session_factory是谁呢?就是我们传入的session,也就是实例化了我们的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))

方法二:

我们发现

class scoped_session(object):
"""Provides scoped management of :class:`.Session` objects. See :ref:`unitofwork_contextual` for a tutorial. """ session_factory = None
"""The `session_factory` provided to `__init__` is stored in this
attribute and may be accessed at a later time. This can be useful when
a new non-scoped :class:`.Session` or :class:`.Connection` to the
database is needed.""" def __init__(self, session_factory, scopefunc=None):
"""Construct a new :class:`.scoped_session`. :param session_factory: a factory to create new :class:`.Session`
instances. This is usually, but not necessarily, an instance
of :class:`.sessionmaker`.
:param scopefunc: optional function which defines
the current scope. If not passed, the :class:`.scoped_session`
object assumes "thread-local" scope, and will use
a Python ``threading.local()`` in order to maintain the current
:class:`.Session`. If passed, the function should return
a hashable token; this token will be used as the key in a
dictionary in order to store and retrieve the current
:class:`.Session`. """
self.session_factory = session_factory if scopefunc:
self.registry = ScopedRegistry(session_factory, scopefunc)
else:
self.registry = ThreadLocalRegistry(session_factory)

如果我们给

scopefunc传值就会走if语句,
class ScopedRegistry(object):
"""A Registry that can store one or multiple instances of a single
class on the basis of a "scope" function. The object implements ``__call__`` as the "getter", so by
calling ``myregistry()`` the contained object is returned
for the current scope. :param createfunc:
a callable that returns a new object to be placed in the registry :param scopefunc:
a callable that will return a key to store/retrieve an object.
""" def __init__(self, createfunc, scopefunc):
"""Construct a new :class:`.ScopedRegistry`. :param createfunc: A creation function that will generate
a new value for the current scope, if none is present. :param scopefunc: A function that returns a hashable
token representing the current scope (such as, current
thread identifier). """
self.createfunc = createfunc
self.scopefunc = scopefunc
self.registry = {} def __call__(self):
key = self.scopefunc()
try:
return self.registry[key]
except KeyError:
return self.registry.setdefault(key, self.createfunc())

我们看到如果对象加括号就会走__call__方法:

第一次没有值,就会走except,设置并且实例化session。

往下方法和方式一一样啦。

在执行到最后我们要加上一句:

session.remove()
我们来看下这句话做了什么?
    def remove(self):
"""Dispose of the current :class:`.Session`, if present. This will first call :meth:`.Session.close` method
on the current :class:`.Session`, which releases any existing
transactional/connection resources still being held; transactions
specifically are rolled back. The :class:`.Session` is then
discarded. Upon next usage within the same scope,
the :class:`.scoped_session` will produce a new
:class:`.Session` object. """ if self.registry.has():
self.registry().close()
self.registry.clear()

我们进入has看下:

    def has(self):
return hasattr(self.registry, "value")

如果有值就执行close方法。

然后在执行clear方法:

    def clear(self):
try:
del self.registry.value
except AttributeError:
pass

SALALchemy Session与scoped_session的源码分析的更多相关文章

  1. SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)

    原生session: from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine from sqlalch ...

  2. springMVC源码分析--国际化实现Session和Cookie(二)

    上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...

  3. [asp.net core 源码分析] 01 - Session

    1.Session文档介绍 毋庸置疑学习.Net core最好的方法之一就是学习微软.Net core的官方文档:https://docs.microsoft.com/zh-cn/aspnet/cor ...

  4. TOMCAT8源码分析——SESSION管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  5. Tomcat源码分析——Session管理分析(下)

    前言 在<TOMCAT源码分析——SESSION管理分析(上)>一文中我介绍了Session.Session管理器,还以StandardManager为例介绍了Session管理器的初始化 ...

  6. Tomcat源码分析——Session管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  7. 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器

    1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...

  8. Flask框架(三)—— 请求扩展、中间件、蓝图、session源码分析

    Flask框架(三)—— 请求扩展.中间件.蓝图.session源码分析 目录 请求扩展.中间件.蓝图.session源码分析 一.请求扩展 1.before_request 2.after_requ ...

  9. Flask框架(五) —— session源码分析

    Flask框架(五) —— session源码分析 目录 session源码分析 1.请求来了,执行__call__方法 2.__call__方法 3.调用__call__方法 3.1.ctx = s ...

随机推荐

  1. Modifying namespace in XML document programmatically

    Modifying namespace in XML document programmatically static XElement stripNS(XElement root) { return ...

  2. cmd 导入数据库文件

    mysql -uroot -p show databases use 库名 source D:\kuming.sql

  3. Abp中自定义Exception的HttpStatusCode

    Abp中在新版本中,抛出的异常(比如:UserFriendlyException)通过AjaxResponse封装后返回的时候,HttpStatusCode默认指定成了500. 对于一些默认封装好的处 ...

  4. 【手记】解决“未能创建 SSL/TLS 安全通道”异常

    之前写了一个桌面程序,程序会间歇性访问某个https接口,一直用的好好的,今天突然报错了,异常就发生在访问接口的地方,曰“请求被中止,未能创建 SSL/TLS 安全通道.”,另外有台电脑也有跑该程序, ...

  5. LInux Crontab及命令

    定时任务(cron job)被用于安排那些需要被周期性执行的命令.利用它,你可以配置某些命令或者脚本,让它们在某个设定的时间内周期性地运行.cron 是 Linux 或者类 Unix 系统中最为实用的 ...

  6. [PHP] 算法-快速排序的PHP实现

    快速排序: 1.基于二分的思想 2.第一个作为基准数,左右各一个指针,同时扫描,右边先走,找到比基准数小的停下 左边再走,找到比基准数大的停下,左右交换 3.当左右相遇的时候,把当前的和基准数调换,递 ...

  7. Linux常用基本命令:tr-替换或者删除字符

    tr命令 作用:从标准输入中替换,缩减或者删除字符,并将结果输出到标准输出 格式:tr [option] [set1] [set2] tr [选项] [字符1] [字符2] 把y替换m, o替换e,并 ...

  8. vue项目未加载完成前显示loading...

    1.在Index.html里面加入loading的元素,让loading元素显示,让app元素隐藏 <!DOCTYPE html> <html> <head> &l ...

  9. CSS 中的 BFC,IFC,GFC和FFC

    原文网址:http://www.cnblogs.com/dingyufenglian/p/4845477.html What‘s FC? 一定不是KFC,FC的全称是:Formatting Conte ...

  10. git命令详解( 八)

    此为记录git的第八篇,前七篇为远程篇,工作中最常用的都在前七篇,因为要在远程分支上合作开发     在提交树上移动 撤销变更 在提交树上移动 在接触 Git 更高级功能之前,我们有必要先学习在你项目 ...