Ginterhauser
Ginterhauser

Reputation: 196

Python executing function on import (apparently)

I am continuing that cryptographical program, and now I'm developing GUI for it. I have weird problem, though: in main menu i have buttons calling out encrypting and decrypting subprograms, but they are apparently being executed BEFORE button is pressed.

definitions.py

#!/usr/bin/env python2.7
#-*- encoding: utf-8 -*
from Tkinter import *
import decoding
import encoding

version="v0.0"


def NewLabel(text, column, row, self):
    label=Label(self, text=text)
    label.grid(column=column,row=row)

def NewButton(text, action, column, row, self, sticky="N"):
    button=Button(self, text=text, command=action)
    button.grid(column=column,row=row,sticky=sticky)

def OnEncode():
    zxc.encode()   #zxc is the new encode
    quit()

def OnDecode():
    decoding.decode(version)

def OnExit():
    quit()

welcome.py

#!/usr/bin/env python2.7
#-*- encoding: utf-8 -*
from Tkinter import *
from definitions import *

import encoding
import decoding
import zxc

main_window=Tk()
mainContainer=Frame(main_window)

NewLabel(u'Welcome to <name> GUI alpha v0.0',0,0,mainContainer)
NewLabel(u'What do you want to do?',0,1,mainContainer)

NewButton(u'1. Encrypt file',OnEncode,0,2,mainContainer)
NewButton(u'2. Decrypt file',OnDecode,0,3,mainContainer)
NewButton(u'Exit',OnExit,0,4,mainContainer)

mainContainer.pack()
main_window.title('<name> GUI')
main_window.mainloop()

zxc.py

#!/usr/bin/env python2.7
#-*- encoding: utf-8 -*
from definitions import *


class encode(Tk):
    def __init__(self,parent):
        Tk.__init__(self,parent)
        self.parent=parent
        self.initialize()

    def harden(number):
        if number<=80: number=53
        elif number>=100: number=((1/2)*number+50)
        elif 82<number<100: number=((number**2-4)*(number**2-1))/number
        return number

    def initialize(self):
        NewLabel('Welcome to <name> GUI v0.0 encoder',0,0,self)



app=encode(None)
app.title('<name> GUI v0.0 encoder')
app.mainloop()

What i get from this is first "Welcome to GUI v0.0 encoder" window, and after i close that "welcome to GUI alpha v0.0" with buttons appears

Upvotes: 1

Views: 212

Answers (2)

Savir
Savir

Reputation: 18418

That's what if __name__ == "__main__" is for.

Check out the great answers provided in this thread: What does if __name__ == "__main__": do?

Let's simplify a bit...

You have a file called... let's say... libmain.py (a quite unfortunate name but... meh) that you want to use as a library (a module you can import somewhere) and as your application main entry point.

Let's make it very trivial: Have that libmain.py file just printing the __name__:

libmain.py:

print "Current __name__: %s" % __name__

Now, create another file (foo.py, for instance) that just imports libmain:

foo.py

import libmain

If you execute python ./libmain.py directly, you'll get this output:

Current __name__: __main__

Whereas if you execute the file that imports libmain (python ./foo.py) you'll get:

Current __name__: libmain

So, to avoid executing code when libmain.py is imported, put that code under an if __name__ == "__main__" (because, as shown in the example above, when libmain is imported, the __name__ will be libmain)

In your particular case, and without knowing the situation in detail, I'd say you're importing welcome (or zxc?) somewhere, and that's what's causing your code to be executed.

Upvotes: 3

Bryan Oakley
Bryan Oakley

Reputation: 385970

When you import a module, all code in that module gets executed. Normally, "executed" means that all of the functions and variables in the module are defined. However, if you include executable code in a module, it will execute.

In your case, zxc.py has code at the bottom which creates some windows. Since you don't protect that code by saying "don't run this on import", it runs on import.

To prevent the code from running, you typically hide this behind an if statement like this:

if __name__ == "__main__":
    <your code here>

__name__ will never be set to the literal string "__main__" when you do an import. It will only be set when you try to directly execute the script.

Upvotes: 1

Related Questions