Pythonscript plugin: how to end the script but not quit Notepad++
-
Thanks for directing me that interesting thread! Possible solutions seem to be indirect:
-
a dummy if-statement with the entire rest of the script indented so that the script reaches the bottom of the file if the statement is untrue
-
defining a function with the body of the main script and calling that conditionally
-
a ‘while true’ loop concluded by ‘break’
My ‘jump to label’ idea was merely an assumption based on my total ignorance of Python. It’s just not possible it seems.
It’s fine for the small stuff I’m trying to do but I reckon this lack of a suitable command could prove annoying for large projects anyone wanted to do based on the plugin…
-
-
@P-Cooper said in Pythonscript plugin: how to end the script but not quit Notepad++:
I reckon this lack of a suitable command could prove annoying for large projects anyone wanted to do based on the plugin…
You reckon wrongly.
Any “large” effort would include “structuring” such that the solutions you call “indirect” are just, well, natural to do.I suppose everyone starts out doing PythonScript with all their statements slammed up against the left side (aka column 1):
x=7 if x==4: pass y=3
etc.
But I’d think/hope most people would “graduate” beyond that type of thing fairly quickly.
BTW, the code snippet above puts x and y into the global namespace where they could possibly accidentally be resused in a bad way by other scripts. The “structure” that I’m talking about would prevent that.
-
I believe that for much of the stuff done in PythonScript, especially by those otherwise unfamilar with Python, a ‘terminate script’ command would be useful and would save some effort, not meaning to say it’s best practice.
Thanks for pointing out that those ‘wall-slammed’ variables aren’t local / temporary. I’ve now slammed
variable = "" / = 0
statements against the wall at the bottom of my scripts, hoping that will do the trick.
-
@P-Cooper said in Pythonscript plugin: how to end the script but not quit Notepad++:
I believe that for much of the stuff done in PythonScript, especially by those otherwise unfamilar with Python, a ‘terminate script’ command would be useful
Something people often don’t understand is that PythonScript is not a programming/scripting language. PythonScript is the plugin; the language is Python.
Thus, the plugin can’t do anything that Python can’t do. For example, you’re asking for something that alters control flow. That’s like asking for PythonScript to offer a slightly different version of Python’s
if
orwhile
keywords. It simply can’t be done.When you’re executing code with the plugin, you’re running Python. PythonScript gives you some extra objects that make working with Notepad++ easier (e.g.
editor
andnotepad
objects), but that’s the extent of it.All other the other “solutions” to the “problem” posed by this thread (found in the linked-to thread) work exactly the same way in pure Python.
So I have advice for “those otherwise unfamilar with Python”, thinking that PythonScript is some lightweight (and simpler) thing… it’s not, so don’t think of it that way.
One key way in which PythonScript’s Python IS different though, is that you can’t end it (its Python interpreter) without exiting Notepad++. With standalone Python, you execute it from a Cmd or PowerShell prompt with:
python myscript.py
. The program runs and control returns to the OS prompt. At that pointmyscript
is gone from memory; its variables don’t “hang around” and can’t mess with the running ofpython my_second_script.py
’s variables. Not so with PythonScript. Since under Notepad++, since the Python interpreter never stops running, variables with global scope remain in the namespace and can be used (if that’s the real intent) in subsequent scripts that are executed.
I’ve now slammed
…
statements against the wall at the bottom of my scripts, hoping that will do the trick.Hmm, it won’t, but maybe I don’t fully understand what you mean… You can’t do a bunch of “hoping” and be successful with programming. :-)
What I do when I’m PythonScripting, and what you’d need to do, to keep things like my
x
andy
from global visibility, is to give them some localized scope.If people just want to “hack away” at Python/Notepad++, doing it the simple “slammed to the left” way is fine, but you can possibly open yourself up to some “strange” bugs sometimes.
Even the simple construct shown before (to solve the problem originally posed):
def main(): x=7 if x == 4: return # <-- this achieves the goal of a "quick exit the script" y=3 main()
protects you from this a good deal, because
x
andy
now “belong” tomain
, so you can’t run into problems with other scripts that might use an (uninitialized)x
andy
(because those won’t exist in the global space). You’d have to refer to them asmain.x
andmain.y
for this to happen, which is much harder to do by accident. Well, unless you usemain
in every script, but even for that case, when you run the above script, it redefinesmain
at every run, so you can’t possibly use an oldmain.x
from another script.So, there are a ton of advantages to using the
def main() / main()
approach; maybe it is just difficult for noobs to get their head around it. I’d say “just do it”.There’s more to the story, and I’ve tried to keep it very simple and not always use totally correct terminology, just in an attempt of simple knowledge transfer…
-
Thanks a lot for sharing your insights in detail.
It was surprising (and seemed unnecessary) to me that
quit() / exit()
andsys.exit()
all shut down Notepad++ rather than just terminate the script, and I thought maybe something could be done about that so that they could do what I had in mind, but as you point out that’s not possible in the Notepad++ environment. It strikes me as odd, though, that it’s not possible for the process to retain that kind of control over the script it’s running – can’t run it in a “new thread” or “sandbox-type thingy”, but I don’t have the foggiest idea about the internals.Well, this noob has finally gotten his head round the
def main() / main()
approach thanks to you and is now proudly using cleaner code! -
@P-Cooper said in Pythonscript plugin: how to end the script but not quit Notepad++:
sys.exit()
Quite frankly, I was surprised the first time I encountered it, that
sys.exit()
will shut down Notepad++.However,
sys.exit()
in standalone Python is a really drastic way of ending a program, and, in practice, isn’t used much in real-world programming. I could go into detail, but perhaps a “trust me” on it will suffice.Since all of your PythonScripting efforts should be considered “real world” :-), “just don’t use
sys.exit()
” is the mantra good PS programmers should chant. -
@Alan-Kilborn
If I ever decide to dabble in Python proper, I’ll bear your advice in mind, thanks! -
@P-Cooper and everyone:
OK, so we’ve hinted a bit at structuring a PythonScript (thus far we’ve been doing it for purposes of easily exiting a running script).
So far, we’ve got this as a minimal technique:
def main(): x = 7 print('x:', x) if x == 4: return # <----- "terminate script" early y = 3 print('y:', y) # ... main()
It works, no doubt about that. If you want to make a template out of it, just delete the demo junk and you’ll have:
def main(): # ... main()
But, if you want to put a bit more “flair” on it, as well as set yourself up for more advanced script-writing in the future, consider this:
# -*- coding: utf-8 -*- from __future__ import print_function # refs: # https://community.notepad-plus-plus.org/topic/24045 from Npp import * #------------------------------------------------------------------------------- class XXXX(object): def __init__(self): x = 7 print('x:', x) if x == 4: return # <----- "terminate script" early y = 3 print('y:', y) # ... #------------------------------------------------------------------------------- if __name__ == '__main__': XXXX()
Things to note:
- the
from __future__
line is only needed if you intend to use “print” statements (for output onto the console) and you’re not using PythonScript 3.x - nice
refs:
section so you can put info about where the script (or parts of it) originated - the
XXXX
should be replaced with a nice “tag” for the script; when I’m doing it, if the name of my file isBarebonesBoilerplateDemo.py
, then instead ofXXXX
, I useBBD
, obviously the capital letter “acronym” of the filename (this is just the way I do it, you can totally go your own way here…) - the “meat” of your script can go entirely in the
__init__
function - if you want/need some additional logical functions (encouraged!), you can certainly do that, like what is shown below:
# -*- coding: utf-8 -*- from __future__ import print_function # refs: # https://community.notepad-plus-plus.org/topic/24045 from Npp import * #------------------------------------------------------------------------------- class XXXX(object): def __init__(self): x = 7 print('x:', x) if x == 4: return # <----- "terminate script" early y = 3 print('y:', y) # ... self.my_function_1(x, y) q = self.my_function_2(y) def my_function_1(self, a, b): print('a:', a, 'b:', b) def my_function_2(self, z): print('z:', z) return z + 6 #------------------------------------------------------------------------------- if __name__ == '__main__': XXXX()
- the
-
-
-
@Alan-Kilborn said in Pythonscript plugin: how to end the script but not quit Notepad++:
because x and y now “belong” to main, so you can’t run into problems with other scripts that might use an (uninitialized) x and y (because those won’t exist in the global space). You’d have to refer to them as
main.x
andmain.y
for this to happenFrom what I can tell, it’s impossible to access variables that way (
main.x
, gives error)… but then it’s even more to your point :)I wonder whether you found advantages to wrapping in a class vs just using nested functions inside main() ?
No need to go in detail ; just curious whether you indeed found advantages or it’s just… a way that also works.
-
@Victorel-Petrovich said in Pythonscript plugin: how to end the script but not quit Notepad++:
I wonder whether you found advantages to wrapping in a class vs just using nested functions inside main() ?
More advanced scripts can have multiple callbacks, and the result of one function can depend on the output of other functions.
Just a simple example (not going to bother writing the script, left as an exercise to the reader):
NOTIFICATION.BUFFERACTIVATED callback: save the current filename to a class variable when the script is invoked: print(the current filename (saved by the callback))
-
@Mark-Olson
Well, when I get to the point that functions won’t suffice, I’ll consider classes.