Menu

Acces the same "namespace"

AlHell
2014-03-10
2014-03-10
  • AlHell

    AlHell - 2014-03-10

    This works in VBA direct:
    Pyexec "b=5"
    ?pyvar(Pyeval ("b"))
    5

    So the functions can access the same names. So far so good.

    If I do something similiar in a Module:

    myscript.py:
    def myPyEval(x):
    return eval(x)
    def myPyExec(x):
    exec x
    return 0

    VBA direct:
    Set modu = PyModule("MyScript", 0, PyPathStr)
    Set res = PyCall(modu, "myPyExec", PyTuple("b=5"))
    Set res2 = PyCall(modu, "myPyEval", PyTuple("b"))

    I do get a "name b is not defined" error.

    How comes and how can I avoid this???

    Thanks for your time!

     
  • Eric Reynolds

    Eric Reynolds - 2014-03-10

    Hi Al,

    I believe this is not so much an issue with ExcelPython as how the eval and exec functions work in Python. I believe the problem is that when you execute b = 5 inside myPyEval it saves the value in the locals dictionary, which is destroyed when Python exits the function. You should specify the locals dictionary you want the statement to be executed or evaluated using, see the Python docs for how to do this.

    Alternatively you can use the PyGet and PySet functions to do something similar, I believe the following should work:

    PySet modu, "b", 5
    Set b = PyGet(modu, "b")
    

    Hope this helps.

    Ciao

     
  • Eric Reynolds

    Eric Reynolds - 2014-03-10

    By the way, you shouldn't rely on

    PyExec "b=5"
    ?PyVar(PyEval ("b"))
    5
    

    to work in your code. It's better to specify a dictionary you want the variables to live in, like this:

    Set locals = PyDict()
    PyExec "b=5", Locals:=locals
    ?PyVar(PyEval("b", Locals:=locals))
    
     
  • AlHell

    AlHell - 2014-03-10

    Hi Eric,

    thank you vermy much for the quick response. It works like you wrote, but...

    What I actually want to do is to do a "import modulexy" interactively, so that I can access the functions of this module xy in other calls. I thougt this doesn't work for the same reasons like the vars in my frist post, but this might be wrong...

    I allways need one MainModule (myscript.py), because there are some commmon functions in it. Then I would like to import some other modules interactively. This all should work in the same "namespace".

    Would it be a possibilty to pass the locals as parameter to the PyCall-Function? I know this is not possible yet...

    Ciao

     
  • Eric Reynolds

    Eric Reynolds - 2014-03-10

    Might this help?

    The key is you need to write them into myscript.py's global dictionary. You can get this by calling the globals() function. So for example:

    def loadDynamic(moduleName, functionName):
        m = __import__(moduleName)
        globals()[moduleName + "_" + functionName] = getattr(m, functionName)
    
     
  • AlHell

    AlHell - 2014-03-10

    It doesn't work compeletely. I inserted the function above in myscript.py.

    I can call it with "loadDynamic('ownmodule', 'ownfunction')" without errors.

    But if I do call "ownfunction" I get the error "name ownfunction is not defined".
    With "ownmodule.ownfuntion" I get "name ownmodule is not defined".

    How do I get this working?

     
  • Eric Reynolds

    Eric Reynolds - 2014-03-10

    The line

    globals()[moduleName + "_" + functionName] = ...
    

    gives you a clue... the function I wrote, in your case, saves the function with the variable name ownmodule_ownfunction, but of course you can modify the code to whatever suits you best.

    For example:

    def loadDynamic(moduleName, functionName, saveToName):
        m = __import__(moduleName)
        globals()[saveToName] = getattr(m, functionName)
    
     
  • AlHell

    AlHell - 2014-03-10

    Aaaaaah, now I got it. Thank you very much for the clarification!!!

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.