[graph-tool] Variable scoping for collect_vertex_marginals

Tiago de Paula Peixoto tiago at skewed.de
Thu Jan 16 12:57:19 CET 2020


Am 16.01.20 um 11:11 schrieb Davide Cittaro:
> Hi again, 
> This is more a python related question, but I'm asking here hoping somebody had a similar issue and worked it out.
> I need to collect vertex marginals during equilibrate and when I do it in my python console everything works just fine (as in the cookbook):
> 
> pv = [None] * len(state.get_levels())
> 
> def collect_marginals(s):
>   global pv
>   pv = [sl.collect_vertex_marginals(pv[l]) for l, sl in enumerate(s.get_levels())]
> 
> gt.mcmc_equilibrate(state, force_niter=10000, mcmc_args=dict(niter=10), callback=collect_marginals)
> 
> as far as understand, every time sl.collect_vertex_marginals is called, it takes as argument the histogram calculated in the previous iterations. 
> My problem is that when I put this code into a function that is imported as a module, scoping is broken and I get an error like
> 
> NameError: name 'pv' is not defined
> 
> Shortly, I have the function nsbm in file _nsbm.py:
> 
> def nsbm(…):
>   […]
>   pv = [None] * len(state.get_levels())
> 
>   def collect_marginals(s):
>     global pv
>     pv = [sl.collect_vertex_marginals(pv[l]) for l, sl in enumerate(s.get_levels())]
> 
>   gt.mcmc_equilibrate(state, force_niter=10000, mcmc_args=dict(niter=10), callback=collect_marginals)
> 
> which is imported 
> 
> from ._nsbm import nsbm
> 
> by the __init__.py of the package module (named tools), then imported by the main
> 
> from . import tools as tl
> 
> the directory structure of the package is (among others)
> 
> scanpy/tools/_nsbm.py
> scanpy/tools/__init__.py
> scanpy/__init__.py
> 
> as far as I understand callback function passed to mcmc_equilibrate is not supposed to return anything, collect_vertex_marginals returns the histogram summing the current to the previous. I think I can't pass pv as an argument to the callback as it becomes local to the function.
> Of course, I'm now reading about variable scoping in python, but if you have any hint it would be greatly appreciated.
> Thanks


You're looking for the nonlocal keyword, instead of global. See here:

https://docs.python.org/3/reference/simple_stmts.html#grammar-token-nonlocal-stmt

-- 
Tiago de Paula Peixoto <tiago at skewed.de>


More information about the graph-tool mailing list