I'm currently making a java GUI (JPanel) that is supposed to display output from a python model. So far I'm trying to have the java code run python, which I have no idea how to do. The main goal is to have both java and python running simultaneously so that any results from the python model can be displayed on the java GUI in real time.
Doing the reverse (running the java GUI in python) could work as well, but the GUI has a lot of settings/packages/JVM arguments that I am not experienced enough to deal with, so I really don't want to go down that route unless I have to.
So far, I have tried ProcessBuilder with BufferReader in java, but that only displays results after the python model finishes running, not in real time. I thought about using Jython, but I heard that it doesn't work for python 3.x versions.
How can I run python in java? If I can't/shouldn't what should I do then?
Is there a way to store the state of the python interpreter embedded in a C program (not the terminal interpreter or a notebook) and restore it later resuming execution were it left off?
Other questions and answers I found about this topic evolved around saving the state of the interactive shell or a jupyter notebook or for debugging. However my goal is to freeze execution and restoring after a complete restart of the program.
A library which achieves a similar goal for the Lua Language is called Pluto, however I don't know of any similar libraries or built-in ways to achieve the same in an embedded python interpreter.
No, there is absolutely no way of storing the entire state of the CPython interpreter as it is C code, other than dumping the entire memory of the C program to a file and resuming from that. It would however mean that you couldn't restart the C program independent of the Python program running in the embedded interpreter. Of course it is not what you would want.
It could be possible in a more limited case to pickle/marshal some objects but not all objects are picklable - like open files etc. In general case the Python program must actively cooperate with freezing and restoring.
I made this script:
from gasp import *
begin_graphics()
Circle((200, 200), 60)
Line((100, 400), (580, 200))
Box((400, 350), 120, 100)
update_when('key_pressed')
end_graphics()
When I start it from terminal, it works perfectly. When I run it from IDLE, it doesn't work, I get no answer (shell prompt (>>>) disappears but nothing happens).
In general, you can't run GUI apps in the embedded Python interpreter in IDLE, unless the library you're using is designed to integrate with IDLE. Or, worse, it may work on one machine and not on another. I'll explain why below, but first just take that on faith.
As far as I can tell, gasp's documentation doesn't address this, but similar libraries either warn you that they may not work in IDLE (easygui, early versions of graphics, etc.) or come with special instructions for how to use them in IDLE (e.g., later versions of graphics).
Now, maybe gasp should be designed to integrate with IDLE, given that it's specifically designed for novices, and many of those novices will be using the IDE that comes built in with Python. Or maybe not. But, even if that should be true, that's something for gasp to deal with. File a bug or feature request, but you'll need some way to keep working until someone gets around to writing the code.
The simplest solution here is to use a different IDE, one that runs its interactive Python interpreter in a completely separate process, exactly the same as you get when running it yourself in the terminal. There are lots of good options out there that are at least free (-as-in-beer) for non-commercial use (PyCharm, Komodo, Eclipse PyDev, emacs with your favorite collection of packages, etc.). Although Stack Overflow is not a good place for advice on picking the best one for you (if googling isn't sufficient, try asking on a mailing list or forum), almost any of them will work.
Another option: instead of using an interpreter built into an IDE, you might want to to consider running an enhanced interpreter environment (like ipython-gtk or emacs with a smaller set of packages) alongside your IDE. Of course they'll no longer be tightly integrated (the "I" in "IDE"), but in my experience, even working in an environment where the whole team uses PyCharm or PyDev, I still end up doing most of my interactive testing in ipython; you may find you prefer that as well. Or you may not, but give it a try and see.
So, why is there a problem in the first place?
First, if you don't understand what an "event loop" or "runloop" or "mainloop" is, please read either Why your GUI app freezes or the Wikipedia page or some other introduction to the idea.
Normally, when you run the interactive Python interpreter (e.g., by typing python at the bash or C: prompt in your terminal), it runs in its own process. So, it can start up a runloop and never return (until you quit), and the terminal won't get in your way.
But when you run the interactive Python interpreter inside IDLE, it's actually running in the same process as IDLE, which has its own runloop. If you start up a runloop and never return, IDLE's runloop doesn't get to run. That means it doesn't get to respond to events from the OS, like "refresh your window" or "prepare for a new window to open", so from the user's (your) point of view, IDLE and your app are both just frozen.
One way to get around this is in your code is to spawn another thread for your runloop, instead of taking over the main thread. (This doesn't work with all GUI libraries, but it works with some. This is how graphics solved the problem.) Another way is to spawn a whole new child process to run your GUI. (This works with all GUI libraries, but it's a lot more workânow you have to deal with inter-process communication. One of the novice-friendly matplotlib wrappers does this.) Finally, you can integrate your runloop with IDLE's Tkinter runloop by having one drive the other. (Not all GUI libraries can be driven this way, but Tkinter's can, and IDLE can be monkeypatched to work this way; graphics used to do this.) But none of these are even remotely simple. And they're probably things that gasp itself should be doing, not your code.
I need to validate phone numbers and there is a very good python library that will do this. My stack however is Go and I'm really not looking forward to porting a very large library. Do you think it would be better to use the python library by running a shell command from within the Go codebase or by running a daemon that I then have to communicate with somehow?
Python, being an interpreted language, requires the system to load the interpreter each time a script is run from the command line. Also
On my particular system, after disk caching, it takes the system 20ms to execute a script with import string (which is plausible for your use case). If you're processing a lot information, and can't submit it all at once, you should consider setting up a daemon to avoid this kind of overhead.
On the other hand, a daemon is more complex to write and test, so you should probably see if a script suits your needs before optimizing prematurely.
There's no answer to your question that fits every possible case. Ultimately, you always have to try the performance with your data and in your system,
I have a multi-threaded program. I want to embed a python interpreter. I don't want to use Python's threading; I want to have multiple copies of the Python interpreter running.
Can I do this? (That is, does Python have global variables, or is everything done with a single Python interpreter object?)
Is there an example of a program that does this?
If I can't do it, my plan is to have multiple Python interpreters, each running in their own address space, and try to do something with inter-process communication. But that seems really hard.
Or is Python multi-threaded well enough now that I can embed it multi-threaded?
Thanks.
Python's interpreter uses global state, and as such you can only have one interpreter per process. You can try using multiprocessing to run multiple processes, each with their own interpreter, but I'm not sure how well that would play with embedding.