1

I'm not a programmer, so I don't even know in what terms should I ask this. Let's say I've compiled a Python script to have an .exe (I use py2exe to do this). This is the major program. Now, I want to add some extra functionality to it, but I don't want to recompile the entire script with the added functionality. I tried to search something on the web, and I found examples of extending a C++ or other application with Python scripts (like a sort of plugin). But I can't figure out how to do it with an application already written in Python.

I tried this: I wrote major.py (this is the script from where I build the executable) and stuff.py. In major I wrote this:

def generic():
    import stuff
    while True:
        param=input('what did you say? ')
        stuff.speak(param)

generic()

And in stuff I wrote this:

def speak(param):
    print(param)

Then I created a .exe with py2exe. It works as expected, when I run the program in the command line says "what did you say?" and waits until I type something, then it prints what I typed. Then, I changed stuff.py with this:

def speak(param):
    print('I said '+param)

Hoping that now upon the execution of the .exe created earlier it would print "I said.." plus whatever I typed. Obviously, it didn't work, the program continued to behave like before. So I'm guessing that once I imported stuff and created the .exe file, that import is permanent, not allowing me to change whatever is in stuff. What should I do?

3 Answers 3

3

py2exe packs the compiled scripts in the executable.

You need to recreate the executable (which will recompile any changed script) to see the changes take effect.

EDIT following the comments: You can do it if you dynamically import/reimport the module from inside the executable.

In your main script you do (see code below)

mod, error = loadmodule('mystuff.py')

if mod is not None:
    # loading succeeded you can now proceed and do things with it
    pass

Of course you have to leave mystuff.py out of the scripts that py2exe packs into the executable. In the above example mystuff.py would be in the same directory as the executable.

The loading code:

def loadmodule(modpath, modname=''):

    if not modpath.endswith('.py'):
        modpath += '.py'

    # generate a random name for the module
    if not modname:
        modpathbase = os.path.basename(modpath)
        modname, _ = os.path.splitext(modpathbase)

    version = (sys.version_info[0], sys.version_info[1])

    if version < (3, 3):
        mod, e = loadmodule2(modpath, modname)
    else:
        mod, e = loadmodule3(modpath, modname)

    return mod, e


def loadmodule2(modpath, modname):
    import imp

    try:
        mod = imp.load_source(modname, modpath)
    except Exception as e:
        return (None, e)

    return (mod, None)


def loadmodule3(modpath, modname):
    import importlib.machinery

    try:
        loader = importlib.machinery.SourceFileLoader(modname, modpath)
        mod = loader.load_module()
    except Exception as e:
        return (None, e)

    return (mod, None)
Sign up to request clarification or add additional context in comments.

3 Comments

Ehh...yes... The thing is that I don't want to recompile the entire program: it's like I have the major program, I know that will not change, but maybe I want to add some new features "on the fly". It would be nice to "add" the new feature to the already compiled script, without recompiling the entire thing
See the edit for how to dynamically load a module into a running Python instance
Brilliant, it works like a charm! I will take a deep look into the documentation for importlib in order to fully grasp the concept, but for now it's perfect, thank you so much!
1

If you run your script from Python, instead of compiling it as an executable, you can make changes and run them without having to recompile. The py2exe is mostly for allowing you to distribute your application to other Windows computers that don't have Python installed. After you have finished developing it, then compile it as an executable so you can run it on other computers.

1 Comment

Yes, I thought of that. The reason why I'm compiling the script is because I want to give the program to another friend without the "hassle" of installing Python and other dependencies on his machine, while retaining the possibility to add new features, if I want to...something like a "patch", so to speak
1

There is no way to do what you want. py2exe builds a standalone python interpreter (In the file named python.dll) with just the dependencies of your project. Then the .exe file runs your script using that interpreter

I suggest you that if you really need to provide regular upgrades then you should recompile it, or install python in the target machine, or make an updating routine that checks for updates and compiles it in the target machine (With py2exe)

1 Comment

Aw, too bad... well, no big deal tho. The idea of an updating routine is very nice, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.