-1

How do I access the namespace of another module or function in python?

For example, let's say I have access to a function f that has been passed, and I want get a variable it has access to.

class function_creator():
  def __init__(self, start_num):
    self.number = start_num


  def getfunc(self):
    def nestedfunc():
      print(f'The number you were trying to find was {self.number}')
      self.number += 1
    return nestedfunc

f = function_creator(5).getfunc()

Running f() will print the number, however I cannot find how to access it directly.

Kyubane
  • 3
  • 1
  • Why do you want to access it directly? In any case, it's available in the `function_creator` object, as `.number`. – juanpa.arrivillaga Apr 14 '20 at 19:33
  • Its all described quite well here: https://stackoverflow.com/a/14414638/642070, in answer to https://stackoverflow.com/questions/14413946/what-exactly-is-contained-within-a-obj-closure. In your case, its at `f.__closure__[0].cell_contents.__dict__["number"]`. This looks a lot like an implementation detail to me... not sure if I'd rely on it. – tdelaney Apr 14 '20 at 19:40

1 Answers1

2

The way you're calling the code, there's not a good way to get at that number. But if you saved the instance of function_creator to a variable, you'd be able to get at it more easily:

fc = function_creator(5)
f = fc.getfunc()

f()
print(fc.number)

While I said there isn't an good way to access the value, it is possible by diving into the internals of the function object, as the function is a closure on the self variable from getfunc. You can get the value of that self argument from f using f.__closure__[0].cell_contents, and then get the number by checking its number attribute:

f = function_creator(5).getfunc()
f()

fc = f.__closure__[0].cell_contents
print(fc.number)

This is CPython specific, and probably won't work in other Python interpreters.

Blckknght
  • 100,903
  • 11
  • 120
  • 169