[graph-tool] Variable scoping for collect_vertex_marginals

Davide Cittaro cittaro.davide at gmail.com
Thu Jan 16 13:00:53 CET 2020


Thanks, for the time being I've solved with a try/except within the function, so that

def foo():
  global pv
  […]
  try:
    pv = [sl.collect_vertex_marginals(pv[l]) for l, sl in enumerate(s.get_levels())]
  except NameError:
   pv =  [None] * len(state.get_levels())

(in fact I've tried to delete the post from the nabble interface...)
Best, 

d

> On 16 Jan 2020, at 12:57, Tiago de Paula Peixoto <tiago at skewed.de> wrote:
> 
> 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>
> _______________________________________________
> graph-tool mailing list
> graph-tool at skewed.de
> https://lists.skewed.de/mailman/listinfo/graph-tool



More information about the graph-tool mailing list