Question

What I am trying to do, is creating a module, with a class; and a function, which is an interface of that class; and a variable name on-the-fly in this function, which is pointing to an instance of that class. This function and the class itself should be in a separate module, and their usage should be in a different python file.

I think, it's much easier to understand what I am trying to do, when you are looking at my code:

This is the first.py:

class FirstClass:
    def setID(self, _id):
        self.id = _id
    def func(self):
        pass

# An 'interface' for FirstClass
def fst(ID):
    globals()['%s' % ID] = FirstClass(ID)
    return globals()['%s' % ID]

Now, if I'm calling fst('some_text') right in first.py, the result is pretty much what I dreamed of, because later on, any time I write some_text.func(), it will call the func(), because some_text is pointing to an instance of FirstClass.

But, when the second.py is something like this:

from first import fst

fst('sample_name')
sample_name.func()

Then the answer from python is going to be like this:

NameError: name 'sample_name' is not defined.

Which is somewhat reasonable.. So my question is: is there a "prettier" method or a completely different one to do this? Or do I have to change something small in my code to get this done?

Thank you!

Was it helpful?

Solution

Don't set it as a global in the function. Instead, just return the new instance from the function and set the global to that return value:

def fst(ID):
    return FirstClass(ID)

then in second.py:

sample_name = fst('sample_name')

where, if inside a function, you declare sample_name a global.

The globals() method only ever returns the globals of the module in which you call it. It'll never return the globals of whatever is calling the function. If you feel you need to have access to those globals, rethink your code, you rarely, if ever, need to alter the globals of whatever is calling your function.

If you are absolutely certain you need access to the caller globals, you need to start hacking with stack frames:

# retrieve caller globals
import sys
caller_globals = sys._getframe(1).f_globals

But, as the documentation of sys._getframe() states:

CPython implementation detail: This function should be used for internal and specialized purposes only. It is not guaranteed to exist in all implementations of Python.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top