UnboundLocalError in TKinter, SQLAlchemy script.

ckava3 at gmail.com ckava3 at gmail.com
Wed Mar 18 06:10:19 EDT 2015


On Wednesday, March 18, 2015 at 12:00:54 AM UTC-4, MRAB wrote:
> On 2015-03-18 02:41, Chris Kavanagh wrote:
> > I have a simple script that takes user input (for an Employee) such as
> > name, age, etc then puts in an sqlite3 database. The script worked fine
> > until I realized one problem. The age input field is defined in
> > SQLAlchemy as an Integer, so if a user inputs a string instead of a
> > number in that field, an error will occur (in IDLE). . .
> >
> > So, I put a try: except clause in the code for the age field in the
> > add_data method. . .
> > try:
> >              age = self.age_var.get()
> >          except ValueError:
> >              showinfo("Error:", "Please Enter A Number In Age Field.")
> >
> > If the user inputs a string (instead of an Int) the showinfo dialogue
> > box opens as it should, but when the user clicks "ok" in the box, I get
> > the error "UnboundLocalError: local variable 'age' referenced before
> > assignment". I tried using a default value above the try: except clause
> > (age=0), which corrects the error, but causes "0" to be saved in the
> > database instead of letting the user choose another value. I want to
> > figure why I get the error (with the try: except clause) and what
> > exactly to do about it. Thanks in advance for any help!
> >
> > Here's the original code (without the try: except clause above). . .Just
> > put the try: except clause in the age variable in the add_data method as
> > shown above to get the error.
> >
> [snip]
> 
> >
> >      def add_data(self):
> >          name = self.name_var.get()
> >          age = self.age_var.get()
> >          addr = self.address_var.get()
> >          city = self.city_var.get()
> >          state = self.state_var.get()
> >          zip = self.zip_var.get()
> >          ssn = self.ssn_var.get()
> >          phone = self.phone_var.get()
> >          cell = self.cell_var.get()
> >          # create new Employee in .db
> >          new_person = Employee(name=name, age=age, address=addr,
> > city=city, state=state, zip=zip, ssn=ssn, phone=phone, cell=cell)
> >          session.add(new_person)
> >          session.commit()
> >          session.close()
> >          self.callback()
> >          return
> >
> Try stepping through the method in your head.
> 
> What happens if the user enters a non-number? A ValueError exception
> occurs. You catch that, show a dialog, but then continue on with the
> remainder of the method.
> 
> Because of the exception, you haven't assigned to 'age', hence the
> UnboundLocalError exception.
> 
> If you assign a default value to age, it'll continue on to where you
> put it into the database.
> 
> Why not just return from the method after showing the dialog?

Thank you. .I didn't understand the way a try: except clause worked. I had thought once you get an exception, it would bounce back to the 'try' part again. Obviously not. Now I understand.

If I use a default value (as you suggest) before the 'try' statement, and the user inputs a string, gets the dialogue, clicks 'ok', then the default value will automatically be entered into the .db. This is not what I want. I want the user to be able to enter the 'age' they want. Without the 'try except' clause, it works fine. although the user doesn't get any message stating why the data didn't save. It will however let the user enter a correct age and click 'Add' & at this point it will save to the .db.

Maybe it's too early here for me to think, lol, but when you say "return from the method after showing the dialogue, I'm not quite sure how to write that. You mean show the dialogue before they enter a value? Could you give me a hint?

Again, thanks for the help! It is appreciated.



More information about the Python-list mailing list