Community

    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Python plugin - handling many scripts...

    Help wanted · · · – – – · · ·
    3
    11
    6820
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DaveyD
      DaveyD last edited by

      Hi, I had a few general questions about using the python plugin. I’ve been benefiting from it for a while now, and my script list keeps on growing more and more… and is getting a little too long.
      Is there a way to handle this?
      (I don’t mind so much the sub-script list, I am mostly speaking about the scripts that appear in the main python menu, in which many of my scripts appear, since only those that appear in this list can be used in shortcuts and in toolbar using Customize Toolbar plugin)

      Thanks
      Davey

      P.S. Just to mention a few ideas: In this regard, there a few ‘better’ options in the javascript plugin for n++:

      1. You can setup customized menus and submenus and have all your scripts listed within
      2. You can add a keyboard shortcut directly from the plugin, no need to go to settings > shortcut mapper
      3. All of the above can be done within one script (or multiple)

      Are any of these options available through python plugin and I’m just missing it?

      1 Reply Last reply Reply Quote 0
      • DaveyD
        DaveyD last edited by

        I would like to add one more part to the question,
        Is it possible to run a python script from a python script?
        This would also help, because then I can have a script that would raise an input box, and I can type in which script I want

        I tried using notepad.runPluginCommand("Python Script", "ScriptName") but I got a message that another script is already running, which I assumed was the current one…

        So, Is this possible any other way?

        Thanks
        Davey

        Claudia Frank 1 Reply Last reply Reply Quote 0
        • Scott Sumner
          Scott Sumner last edited by

          For the running-a-pythonscript-file-from-another part of your question, have a look at the execfile() function.

          1 Reply Last reply Reply Quote 0
          • DaveyD
            DaveyD last edited by

            Hi Scott, thanks for replying
            I did not try this yet, but I do have a question:
            I want the other_script_file to be run in n++ to make changes to the text. The execFile() is a python function, not a n++ function - does this work?

            Thanks,
            Davey

            1 Reply Last reply Reply Quote 0
            • Scott Sumner
              Scott Sumner last edited by

              Should work. Try it out in some simple test first, before investing a lot of time architecting something bigger that could perhaps not work for your situation.

              1 Reply Last reply Reply Quote 0
              • Claudia Frank
                Claudia Frank @DaveyD last edited by

                Hello Davey,

                part1 - no, as you already said,

                • main python script menu,
                • toolbar (but no need of extra plugin)
                • and context menu (with a level of one folder)

                can be used to access scripts faster.

                part2 - not really, Python Script plugin doesn’t allow execution of multiple scripts at the same time
                but you can overcome this by using the python way - import might be your friend.

                Might, because you need to start writing the code a little bit different and you need to be aware
                what import really means.

                When importing a python module, which isn’t really different to any other python script, the loader
                executes every code which isn’t secured.

                I guess I better explain it by a simple example.

                Assuming you have 2 python scripts

                • main_test.py
                • test1.py

                The main_test.py is, as the name suggest ;-), the script which you use to execute other scripts
                therefore it has the following line in it.

                import test1
                

                test1.py scripts does have the lines

                from Npp import *
                
                console.write('test1.py\n')
                

                now if you execute main_test.py you will see that python script console shows test1.py as message.
                So what you need to do to secure it, you need to take care that every code is encapsulated in a function.

                from Npp import *
                
                def main():
                    console.write('test1.py\n')
                

                Now you can import it from main_test and nothing gets executed automatically.
                Run an inputbox, choose the script you want and execute it like

                test1.main()
                

                name_of_the_module.name_of_the_function

                If you import it like

                import test1 as t
                

                then execution would be

                t.main()
                

                But now there is another issue. You cannot run test1.py independently. To overcome this
                you need to add the following lines to the end of the test1 script

                if __name__ == "__main__":
                    main()
                

                or any other extra code which is needed to execute it independently.

                if __name__ == "__main__":
                    console.write('now i'm called directly\n')
                    main()
                

                Done.

                As you see, test1.py needs to import Npp because every module/python script which get imported
                will be imported to the local context and doesn’t have access to the global context automatically.

                Cheers
                Claudia

                1 Reply Last reply Reply Quote 1
                • DaveyD
                  DaveyD last edited by

                  Hi Claudia
                  Thanks for your detailed response! Sounds great!
                  I happen to know a little about importing - I have made my own module with basic functions that I use often (e.g., getWord() to get current word etc.)
                  However, I didn’t know about this

                   if __name__ == "__main__":
                  

                  What does this mean and do exactly?
                  How does it work - you write the function that you want to run? (I.e., in your case, the function name was “main” so you wrote “main”, but what if I have a different function name - do I declare that name, or should I just create one which guides the script?)

                  Thanks,
                  Davey

                  Claudia Frank 1 Reply Last reply Reply Quote 0
                  • Claudia Frank
                    Claudia Frank @DaveyD last edited by Claudia Frank

                    Hello Davey,

                    as said, the python interpreter reads your module/python script and executes all insecure code. Don’t know how to say this better.
                    Before it is done, the interpreter sets some special variables like __name__ and its value is __main__ only if this file is the main file.
                    ( Btw there is an agreement in the python community that you shouldn’t mess with variables already defined which start with an
                    underscore. Variables defined by you can, of course, treated as you like)

                    E.g. python.exe myfile.py

                    means, that __main__ refers to myfile.py and all code within will be executed, as long as everything is correct of course.

                    If myfile.py has an import mymodule then it’s __name__ variable is set to mymodule instead.
                    So if the mymodule gets loaded the interpreter doesn’t find __name__ == __main__ and does not execute code
                    which is under this if statement. Other code gets executed.
                    Instead you need to explicitly call it via mymodule.myfunction.

                    So this line is simply a way to secure code against running.

                    Is this more understandable? I guess if you do the steps I described you will get it.

                    Cheers
                    Claudia

                    1 Reply Last reply Reply Quote 0
                    • DaveyD
                      DaveyD last edited by DaveyD

                      Thanks Claudia!
                      Your suggestion works perfectly!

                      This is what i experienced:

                      1. When I ran the code with if __name__ == "__main__":main() everything worked perfectly
                      2. When I removed the if statement, and just wrote main(), the script got ran 2 times - I’m understanding, once while importing with the import statement, and then again when the script called it
                      3. When I run that script directly, it works in both instances (with and without the if condition)

                      As to why this is true, here is what I understood from testing:

                      1. When the script is called directly, the __main__ variable is always "__main__", which means… (not sure)
                      2. When the script is imported into a different script, the __main__ variable is set to the name of the script being imported!
                      3. When the script is called from another script, then it is similar to running it directly, and the __main__ variable is set to "__main__"

                      And after I wrote all that… I now can say that I understand your previous posts!

                      Thank you very much Claudia!
                      Davey

                      Claudia Frank 1 Reply Last reply Reply Quote 0
                      • Claudia Frank
                        Claudia Frank @DaveyD last edited by

                        Hello Davey,

                        no, __name__ is the variable, __main__ the value.
                        consider the following in a script which gets imported by another script

                        from Npp import *
                        
                        console.write('imported or called directly\n')
                        
                        if __name__ == "__main__":
                            console.write('only if called directly\n')
                        

                        if your scripts imports it you will only see the line 'imported or called directly
                        if you run the script directly you will see both.

                        Why the need of this if…

                        You want to write a module which provides some basic function to other scripts.
                        Like, you have a convert module which converts what ever you want. Instead of writing the
                        function in evey script again and again you write a module and import it. I know you know this.
                        But what if you want to set up test routines which should check if the module is still working
                        after you have modified it? You don’t use another script to test it you write your test case under the if clause.
                        So they get not executed when some other script is importing it but when you call it directly.

                        Cheers
                        Claudia

                        1 Reply Last reply Reply Quote 0
                        • DaveyD
                          DaveyD last edited by DaveyD

                          Hey Claudia!
                          Nice! I understand now fully!
                          (I got mixed up with the name of the variable and the value…)

                          You’re wonderful!!
                          Thank you
                          Davey

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Copyright © 2014 NodeBB Forums | Contributors