0

I have kind of a tricky question, so that it is difficult to even describe it. Suppose I have this script, which we will call master:

#in master.py
import slave as slv
def import_func():
    import time
slv.method(import_func)

I want to make sure method in slave.py, which looks like this:

#in slave.py
def method(import_func):
    import_func()
    time.sleep(10)

actually runs like I imported the time package. Currently it does not work, I believe because the import stays exists only in the scope of import_func(). Keep in mind that the rules of the game are:

  1. I cannot import anything in slave.py outside method
  2. I need to pass the imports which method needs through import_func() in master.py
  3. the procedure must work for a variable number of imports inside method. In other words, method cannot know how many imports it will receive but needs to work nonetheless.
  4. the procedure needs to work for any import possible. So options like pyforest are not suitable.

I know it can theoretically be done through importlib, but I would prefer a more straightforward idea, because if we have a lot of imports with different 'as' labels it would become extremely tedious and convoluted with importlib. I know it is kind of a quirky question but I'd really like to know if it is possible. Thanks

Unziello
  • 103
  • 8

1 Answers1

0

What you can do is this in the master file:

#in master.py
import slave as slv
def import_func():
    import time
    return time
slv.method(import_func)

Now use time return value in the slave file:

#in slave.py
def method(import_func):
    time = import_func()
    time.sleep(10)

Why would you have to do this? It's because of the application's stack. When import_func() is called on slave.py, it imports the library on the stack. However, when the function terminates, all stack data is released from memory. So the library would get released and collected by the garbage collector.

By returning time from import_func(), you guarantee it continues existing in memory once the function terminates executing.

Now, to import more modules? Simple. Return a list with multiples modules inside. Or maybe a Dictionary for simple access. That's one way of doing it.


[Edit] Using a dictionary and importlib to pass multiple imports to slave.py:

master.py:

import test2 as slv
import importlib

def master_import(packname, imports={}):
    imports[packname] = importlib.import_module(packname)

def import_func():
    imports = {}
    master_import('time', imports)

    return imports

slv.method(import_func)

slave.py:

#in slave.py
def method(import_func):
    imports = import_func()
    imports['time'].sleep(10)

This way, you can literally import any modules you want on master.py side, using master_import() function, and pass them to slave script.

Check this answer on how to use importlib.

Carl HR
  • 776
  • 5
  • 12
  • That will not work because I would need to add an unspecified amount of import module variables both to the return and to the variable gathering them in method. In other words, there is no way to make it adjustable for a variable number of imports. But rightfully so, I did not specify this in the question, so now I will edit it to add this. – Unziello May 17 '22 at 20:49
  • Just check out my edit, if that's what you meant. I just tested the script, even for submodules, and it works. – Carl HR May 17 '22 at 21:09
  • Nice compact implementation! This might be good enough. I'll give it some thought. Thank you! – Unziello May 17 '22 at 22:11