据我了解,上下文管理器在Python中用于定义对象的代码段(__enter__和__exit__)的初始化和完成。但是,在PyMC3的教程中,它们显示了以下上下文管理器示例:basic_model = pm.Model()with basic_model: # Priors for unknown model parameters alpha = pm.Normal('alpha', mu=0, sd=10) beta = pm.Normal('beta', mu=0, sd=10, shape=2) sigma = pm.HalfNormal('sigma', sd=1) # Expected value of outcome mu = alpha + beta[0]*X1 + beta[1]*X2 # Likelihood (sampling distribution) of observations Y_obs = pm.Normal('Y_obs', mu=mu, sd=sigma, observed=Y)并提到这有关联的变量的目的alpha,beta,sigma,mu和Y_obs对模型basic_model。我想了解这种机制是如何工作的。在我发现的上下文管理器的说明 中,我没有看到任何暗示在上下文块中定义的变量或对象如何以某种方式“关联”到上下文管理器的建议。似乎库(PyMC3)以某种方式可以访问“当前”上下文管理器,因此它可以在幕后将每个新创建的语句与其关联。但是库如何获得对上下文管理器的访问?
2 回答
POPMUISE
TA贡献1765条经验 获得超5个赞
PyMC3通过将线程局部变量作为类内部的Context
类变量进行维护来实现。Model
的继承自Context
。
每次您调用with
模型时,当前模型都会被推送到特定于线程的上下文堆栈中。因此,堆栈的顶部始终引用用作上下文管理器的最里面(最新)的模型。
Context
s(因此Model
s)具有一个类方法来获取上下文堆栈的顶部。.get_context()
Distribution
Model.get_context()
创建它们以使其与最内层模型相关联时调用。
简而言之:
with model
推model
送到上下文堆栈。这意味着该with
块内部,type(model).contexts
或Model.contexts
或Context.contexts
现在包含model
作为其最后一个(最顶部)元素。Distribution.__init__()
调用Model.get_context()
(请注意capitalM
),它返回上下文堆栈的顶部。在我们的例子中是model
。上下文堆栈是线程本地的(每个线程一个),但是它不是特定于实例的。如果只有一个线程,那么无论模型数量如何,也只有一个上下文堆栈。退出上下文管理器时。
model
从上下文堆栈中弹出。
添加回答
举报
0/150
提交
取消