pydata

Keep Looking, Don't Settle

namespace in python import

Introduction

I prepated a piece of code to calculate the lifetime expected loss for IFRS9 purpose. However, the calculation has to be modified from time to time for testing purpose. To make it simple, I put the calculation engine function in separate file to be imported into the main function. In this way, if I need to modify the calc engine, I dont need to modify every calculation files.

The structure will be like calc_engine.py: which is the calculation function called calc_engine main.py: include read in saved predicted pd/lgd/ead/prepayment and the snapshot data for calculation. It also use the multiple processing to call the calc_engine to do the calculation.

The issue is: data and pd/lgd/data are imported in main.py and are passed into calc_engine for calculation. In this way, python will issue error: NameError: global name 'pd_lgd' is not defined.

Answer

Globals in Python are global to a module, not across all modules. (Many people are confused by this, because in, say, C, a global is the same across all implementation files unless you explicitly make it static.)


There are different ways to solve this, depending on your actual use case.

  • write a class rather than a function in calc_engine.py and let the data to be used as the parameter in the class.
import calc_engine
mycalc = module1.ClacEngine(pd = pd_data, lgd = lgd_data)
mycalc.calc_function()
  • If you really do want a global, but it's just there to be used by module1, set it in that module.
import calc_engine
calc_engine.pd = pd_data
calc_engine.snapshot_data = snapshot_data

map(calc_engine.calc_function, snapshot_data)
  • On the other hand, if it is shared by a whole lot of modules, put it somewhere else, and have everyone import it:
import shared_stuff
import calc_engine

shared_stuff.pd = pd_data
shared_stuff.snapshot_data = snapshot_data

map(calc_engine.calc_function, snapshot_data)

and, in calc_engine.py:

import shared_stuff
def fcalc_function():
    f(data)
  • Finall, Or, in the rare case that you really do need it to be truly global everywhere, like a builtin, add it to the builtin module. The exact details differ between Python 2.x and 3.x. In 3.x, it works like this:
import builtins
import calc_engine
builtins.snapshot_data = snapshot_data

map(calc_engine.calc_function, snapshot_data)

Reference

  1. Python - Visibility of global variables in imported modules

  2. How to create module-wide variables in Python?