1

I have two Python files:

b.py:

def buzz():
    foobar = Foobar()

c.py:

from b import buzz

class Foobar:
    pass

buzz()

Running python c.py raises:

NameError: name 'Foobar' is not defined

Looks like there is a basic Python's import mechanism I still don't understand. I would expect that, when buzz() is called, it has dynamically access to the environment now containing Foobar.


Of course (?), if I replace the importation of buzz by its definition, it works:

d.py:

def buzz():
    foobar = Foobar()

class Foobar:
    pass

buzz()

Context.

This may be an XY-problem. Ultimately, I want to be able to change the behaviour of buzz depending on which Foobar variant has previously been imported. However, I would be interested in understanding why b.py / c.py fails.

Aristide
  • 3,606
  • 2
  • 30
  • 50
  • 2
    Python is lexically scoped ("A function sees its surroundings"). Pass things as arguments to move them between scopes. – MisterMiyagi Oct 03 '21 at 11:50
  • The difference between "environment" and "surroundings" is not clear for me, but your comment leads me to https://stackoverflow.com/questions/51604346/does-python-scoping-rule-fits-the-definition-of-lexical-scoping, which cites this helpful definition of lexical scoping: "The body of a function is evaluated in the environment where the function is defined, not the environment where the function is called." – Aristide Oct 03 '21 at 12:13
  • Regardless of other aspects, you have a circular import dependency going here. B needs foobar which is defined in c. C imports b. Not gonna work. – JL Peyret Oct 03 '21 at 16:47

1 Answers1

1

buzz function's definition is in module "b.py". This means when the body of the buzz is being executed(buzz() in c.py), interpreter jumps into module b. Module b's global namespace is where body of the buzz function can access global variables not c's global namespace and of course there is no "Foobar" in module b's globals().

In LEGB rule, "G" points to the module's global namespace which the interpreter is currently in, not other modules' global namespace.

S.B
  • 13,077
  • 10
  • 22
  • 49