Using functions outside a class..

This is the place for queries that don't fit in any of the other categories.

Using functions outside a class..

Postby PhpGuy » Sat Oct 05, 2013 10:00 am

Hi all, first time posting here so please be gentle with me. :lol:

Guys and gals, as you can see by my username I am a PhpGuy trying to get to grips with Python.
I've had a play around with Python/Pygame/Tkinter and I am very impressed with what i've seen so far.

The scripts i've written i have placed into a library to keep for future use. Now I am trying to tackle classes/imports/modules etc.

So, the reason i'm here...
I have created a forms class (which forms a base - no pun intended ;) ) and a personal details form to capture user details for adding to a database.

I have this 'myapp.py' script:
Code: Select all
from Tkinter import Tk, mainloop

import sys
sys.path.append('mod')

# Import the forms
from forms.personalDetailsClass import personalDetails

def buton_pressed(FORM_VALUES):
    print FORM_VALUES

#
# The bones of the app..
def main():
    root = Tk()

    # Setup the class as a standalone window.
    personal_details = personalDetails(root)

    # Add the title to the main label.
    personal_details.titletext.set('Add New Student')

    # Run the mainloop.
    root.mainloop()
   

# Run the software.
if __name__ == "__main__":
    main()


Here is the line from the personal details form class file:
Code: Select all
self.submitbutton = Button(self.window, text='Add', command=buton_pressed)


Now here is where I'm stumped...
Inside the class, i am trying to send the data (when the button is pressed) to a function outside the class but it keeps throwing an error telling me the buton_pressed function is not defined. Why?
In Php, if i imported (include/require) a file, anything below the import line could use the imported file, anything above the line, the imported file could use.

Why is my script throwing errors at me? how do imports work in Python?

Any help would be greatly appreciated,
Cheers,
Pete.

Edit:
If i place the function inside the same file as the class, all works fine.
If i place the class in my main file, it works.
Just can't seem to get it to work when they are separated :?
PhpGuy
 
Posts: 6
Joined: Sat Oct 05, 2013 9:31 am

Re: Using functions outside a class..

Postby Yoriz » Sat Oct 05, 2013 10:36 am

Hi,

buton_pressed is local to myapp.py
to access it in another module you would need to use
Code: Select all
import myapp
...
...
...
myapp.button_pressed
New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Spam topic disapproval technician
Windows7, Python 2.7.4., WxPython 2.9.5.0., some Python 3.3
User avatar
Yoriz
 
Posts: 782
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: Using functions outside a class..

Postby PhpGuy » Sat Oct 05, 2013 10:46 am

if i added import myapp to the top of the forms class file would that not cause an infinite loop as the myapp file is already importing the forms class?

Edit:
Here are my three files:
myapp.py
Code: Select all
from Tkinter import Tk, mainloop

import sys
sys.path.append('mod')

# Import the forms
from forms.personalDetailsClass import personalDetails

def but_pres(FORM_VALUES):
    print FORM_VALUES

#
# The bones of the app..
def main():
    root = Tk()
    # Setup the class as a standalone window.
    personal_details = personalDetails(root)

    # Add the title to the main label.
    personal_details.titletext.set('Add New Student')
   
    # Run the mainloop.
    root.mainloop()
   

# Run the software.
if __name__ == "__main__":
    main()



myFormsClass.py
Code: Select all
from Tkinter import *

class myForms:
    #
    # Constants.
    #
    WINDOW_TITLE    = 'My Forms'
    WINDOW_WIDTH    = 100
    WINDOW_HEIGHT   = 100
    #
    FONT_FACE       = 'Helvetica'
    FONT_SIZE       = 14
    FONT_WEIGHT     = 'bold'
    #
    LABEL_BG_COLOUR = 'blue'
    LABEL_FG_COLOUR = 'white'
    #
    LABEL_ANCHOR    = 'w'
    LABEL_STICKY    = 'ew'
    #
    FORM_VALUES     = {}
   
    #
    # setup the bones of the class.
    def __init__(self, parent):
        # Set a reference to self.parent for later use.
        self.parent = parent
        # Setup the class as a Toplevel window. (child)
        self.window = Toplevel()
        # Window Title
        self.window.wm_title(self.WINDOW_TITLE)
        #
        # calculate the x, y positions by screen size (centered)
        xpos = (self.window.winfo_screenwidth() / 2) - (self.WINDOW_WIDTH  / 2)
        ypos = (self.window.winfo_screenheight() / 2) - (self.WINDOW_HEIGHT / 2)
        # size and place the window.
        self.window.wm_geometry('%dx%d+%d+%d' % (self.WINDOW_WIDTH, self.WINDOW_HEIGHT, xpos, ypos))
        #
        # enable element resizing.
        self.window.grid_columnconfigure(0, weight=1)
        #
        # disallow main window resizing.
        self.window.resizable(False, False)
       
        # call the create widgets function.
        self.create_widgets()
   
    # Create the widgets.
    def create_widgets(self):
        # create the main label.
        self.titletext = StringVar()
        self.titletext.set('My First Form')
        self.titletextlabel = Label(self.window, textvariable=self.titletext, font=(self.FONT_FACE, self.FONT_SIZE, self.FONT_WEIGHT), anchor=self.LABEL_ANCHOR, fg=self.LABEL_FG_COLOUR, bg=self.LABEL_BG_COLOUR, relief=RAISED, pady=20)


personalDetailsClass.py
Code: Select all
from myFormsClass import *

class personalDetails(myForms):
    WINDOW_WIDTH   = 300
    WINDOW_HEIGHT  = 500
   
    # Create the widgets.
    def create_widgets(self):
        # Call the base class create_widgets method to include the title label.
        myForms.create_widgets(self)
        #
        # Create new widgets.
        #
       
        self.fnameentrytext = StringVar()
        self.lnameentrytext = StringVar()
        self.doornumbertext = StringVar()
        self.postcodetext   = StringVar()

        # first name.
        self.fnamelabel = Label(self.window, text='First Name', anchor=self.LABEL_ANCHOR, padx=4, pady=4)
        self.fnameentry = Entry(self.window, textvariable=self.fnameentrytext)
        # last name.
        self.lnamelabel = Label(self.window, text='Last Name', anchor=self.LABEL_ANCHOR, padx=4, pady=4)
        self.lnameentry = Entry(self.window, textvariable=self.lnameentrytext, width=25)
        # Address.
        self.addresslabel = Label(self.window, text='Address', anchor=self.LABEL_ANCHOR, padx=4, pady=4)
        self.doornumberlabel = Label(self.window, text='House Number', anchor=self.LABEL_ANCHOR, padx=4, pady=4)
        self.doornumberentry = Entry(self.window, textvariable=self.doornumbertext, width=25)
        self.postcodelabel = Label(self.window, text='Postcode', anchor=self.LABEL_ANCHOR, padx=4, pady=4)
        self.postcodeentry = Entry(self.window, textvariable=self.postcodetext, width=25)
       
        self.submitbutton = Button(self.window, text='Add', command=but_pres)
        # Call the method to place the widgets.
        self.place_widgets()


    # Place the widgets.
    def place_widgets(self):
        #
        # Place the widgets.
        #
        # Place the main title label.
        self.titletextlabel.grid(column=0, row=0, columnspan=2, sticky=self.LABEL_STICKY)
        self.fnamelabel.grid(column=0, row=1, sticky=self.LABEL_STICKY)
        self.lnamelabel.grid(column=1, row=1, sticky=self.LABEL_STICKY)
        self.fnameentry.grid(column=0, row=2, sticky=self.LABEL_STICKY)
        self.lnameentry.grid(column=1, row=2, sticky=self.LABEL_STICKY)
        self.addresslabel.grid(column=0, row=3, columnspan=2, sticky=self.LABEL_STICKY)
        self.doornumberlabel.grid(column=0, row=4, sticky=self.LABEL_STICKY)
        self.postcodelabel.grid(column=1, row=4, sticky=self.LABEL_STICKY)
        self.doornumberentry.grid(column=0, row=5, sticky=self.LABEL_STICKY)
        self.postcodeentry.grid(column=1, row=5, sticky=self.LABEL_STICKY)
       
        #
        self.submitbutton.grid(column=0, row=10, columnspan=2, sticky=self.LABEL_STICKY)
   


any help on the current problem (or anything glaringly obvious to the more advanced Python(ist) would be appreciated.
Cheers,
Pete.
PhpGuy
 
Posts: 6
Joined: Sat Oct 05, 2013 9:31 am

Re: Using functions outside a class..

Postby Yoriz » Sat Oct 05, 2013 11:22 am

New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Spam topic disapproval technician
Windows7, Python 2.7.4., WxPython 2.9.5.0., some Python 3.3
User avatar
Yoriz
 
Posts: 782
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: Using functions outside a class..

Postby PhpGuy » Sat Oct 05, 2013 12:39 pm

Thanks for the link. I get it now :)

As a sidenote, Is it ok to place imports at the bottom of a script?
I know it's possible, what I mean is, do the Python community generally frown upon this behaviour? (Should I restructure my code?)

In php, best practice is to put includes at the top for the sake of easy reading/updating.

Pete.
PhpGuy
 
Posts: 6
Joined: Sat Oct 05, 2013 9:31 am

Re: Using functions outside a class..

Postby Yoriz » Sat Oct 05, 2013 1:04 pm

Best practice is to put imports at the top.

From pep8
pep8 wrote:Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Spam topic disapproval technician
Windows7, Python 2.7.4., WxPython 2.9.5.0., some Python 3.3
User avatar
Yoriz
 
Posts: 782
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: Using functions outside a class..

Postby PhpGuy » Sat Oct 05, 2013 2:00 pm

Thanks again, two good reads you pointed me at there, much appreciated. ;)

Having read through pep8 and looking at my code, I see a lot of "don't do this" in my code..
Looks like I be re-writing it all.

Trying to 'leave php at the door' whilst writing python is a lot harder than I thought as I keep thinking 'what would I do in php' and I believe that could be causing me some self inflicted issues! :(

Thanks again for your help. ;)
PhpGuy
 
Posts: 6
Joined: Sat Oct 05, 2013 9:31 am


Return to General Coding Help

Who is online

Users browsing this forum: gorond, snippsat and 3 guests