我们如何才能将Python上下文管理器“关联”到其块中出现的变量?

据我了解,上下文管理器在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)以某种方式可以访问“当前”上下文管理器,因此它可以在幕后将每个新创建的语句与其关联。但是库如何获得对上下文管理器的访问?


小唯快跑啊
浏览 150回答 2
2回答

POPMUISE

PyMC3通过将线程局部变量作为类内部的Context类变量进行维护来实现。Model的继承自Context。每次您调用with模型时,当前模型都会被推送到特定于线程的上下文堆栈中。因此,堆栈的顶部始终引用用作上下文管理器的最里面(最新)的模型。Contexts(因此Models)具有一个类方法来获取上下文堆栈的顶部。.get_context()DistributionModel.get_context()创建它们以使其与最内层模型相关联时调用。简而言之:with model推model送到上下文堆栈。这意味着该with块内部,type(model).contexts或Model.contexts或Context.contexts现在包含model作为其最后一个(最顶部)元素。Distribution.__init__()调用Model.get_context()(请注意capital M),它返回上下文堆栈的顶部。在我们的例子中是model。上下文堆栈是线程本地的(每个线程一个),但是它不是特定于实例的。如果只有一个线程,那么无论模型数量如何,也只有一个上下文堆栈。退出上下文管理器时。model从上下文堆栈中弹出。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python