2014-11-19 6 views
0

Итак, я создаю свою первую программу на Python, и все это составлено из крошечных частей, и мне не удается собрать все это вместе.Непонятно, как исправить эту ошибку.

Код, который я извлек для этого пост в основном входе в систему, используя Premade .txt под названием «yournamehere profile.txt», где первые 2 строки имеют имя пользователя и пароль, который проверяется и позволяет войти in.

Тогда у меня есть это, поэтому вы можете войти и ввести свои данные, однако я получаю сообщение об ошибке: TypeError: дескриптор 'write' требует объекта 'file', но получил 'str', который после просмотра Я предполагаю, что файл не открыт в правильной части кода.

Я извиняюсь, если мой код грязный или плохо сделано, это мой первый когда-либо программа, так что если у вас есть какие-либо советы или способы, чтобы сделать его лучше, я буду ценить тех, тоже: P

from Tkinter import * 

root = Tk() 
root.configure(bg="#CCFFCC") 

#========--------------PERSONAL DETAILS START-------------==========# 
def Personal(): 
    Personal=Toplevel(root) 
    Personal.title("Personal Details") 
    Personal.configure(bg="#CCFFCC") 
    #----COMMANDS W/ WIDGETS----# 
    #First Name 
    def WriteFName(): 
     file.write("\n") 
     file.write("First Name: ") 
     file.write(str(entryFName.get())) 
     file.write("\n") 
     labelSaveFName.configure(text="Saved") 
    labelFName = Label(Personal, text="First name: ", bg="#ccffcc") 
    entryFName = Entry(Personal) 
    buttonFName = Button(Personal, text="Save", command=WriteFName, bg="#93FF00") 
    labelSaveFName = Label(Personal, text="...", bg="#ccffcc") 
    #Last Name 
    def WriteLName(): 
     file.write("Last Name: ") 
     file.write(str(entryLName.get())) 
     file.write("\n") 
     labelSaveLName.configure(text="Saved") 
    labelLName = Label(Personal, text="Last name: ", bg="#ccffcc") 
    entryLName = Entry(Personal) 
    buttonLName = Button(Personal, text="Save", command=WriteLName, bg="#93FF00") 
    labelSaveLName = Label(Personal, text="...", bg="#ccffcc") 
    #Age 
    def WriteAge(): 
     file.write("Age: ") 
     file.write(str(entryAge.get())) 
     file.write("\n") 
     labelSaveAge.configure(text="Saved") 
    labelAge = Label(Personal, text="Age: ", bg="#ccffcc") 
    entryAge = Entry(Personal) 
    buttonAge = Button(Personal, text="Save", command=WriteAge, bg="#93FF00") 
    labelSaveAge = Label(Personal, text="...", bg="#ccffcc") 
    #----GRID----# 
    labelFName.grid(row=0, column=0) 
    entryFName.grid(row=0, column=1) 
    buttonFName.grid(row=0, column=2) 
    labelSaveFName.grid(row=0,column=3) 
    labelLName.grid(row=1, column=0) 
    entryLName.grid(row=1, column=1) 
    buttonLName.grid(row=1, column=2) 
    labelSaveLName.grid(row=1, column=3) 
    labelAge.grid(row=2, column=0) 
    entryAge.grid(row=2, column=1) 
    buttonAge.grid(row=2, column=2) 
    labelSaveAge.grid(row=2, column=3) 

#=================--------PERSONAL DETAILS END-------================# 

#=====----CHOOSING WHAT TO INPUT START----=====# 
def details(): 
    detailswindow=Toplevel(root) 
    detailswindow.configure(bg="#CCFFCC") 
    detailswindow.title("Choose") 
    def end(): 
     detailswindow.destroy() 
    #---WIDGETS---# 
    PersonalButton = Button(detailswindow, text="Personal Details", command=Personal, bg="#93ff00") 
    CloseButton = Button(detailswindow, text="Close Window", command=end, bg="#93ff00") 
    #---GRID---# 
    PersonalButton.grid(row=0, column=0) 
    CloseButton.grid(row=1, column=1) 
#=====----CHOOSING WHAT TO INPUT END----=====# 

#======----LOG-IN WINDOW START----======# 
def newwindow(): 
    login=Toplevel(root) 
    login.configure(bg="#CCFFCC") 
    name=raw_input("Please enter your name: ") 
    file = open(name.lower() + " profile.txt", "a+") 
    #---Commands---# 
    def end(): 
     login.destroy() 
    def callback(): 
     line = file.readlines() 
     username = user.get() 
     password = passw.get() 
     if username == line[0].strip() and password == line[1].strip(): 
      Message.configure(text = "Logged in.") 
      proceed.configure(text="Proceed", command=details) 
     else: 
      Message.configure(text = "Username and password don't match the account \n under the name;\n \'" + name + "\'. \nPlease try again.") 
     return f 
    #---LOG-IN WIDGETS---# 
    #labels 
    LogInTitle = Label(login, text="Please log in.", bg="#CCFFCC").grid(row=0, column=1) 
    UserTitle = Label(login, text="Username:", bg="#CCFFCC").grid(row=1, column=0) 
    PassTitle = Label(login, text="Password:", bg="#CCFFCC").grid(row=2, column=0) 
    Message = Label(login, bg="#CCFFCC") 

    #text entry windows 
    user = Entry(login) 
    passw = Entry(login, show='*') 

    #buttons 
    go = Button(login, text="Log in!", command = callback, bg="#93ff00").grid(row=3, column=1) 
    proceed = Button(login, text="...", bg="#93ff00") 
    close = Button(login, text="Close window", command=end, bg="#93FF00") 
    #===--LOG-IN GRID===--# 
    user.grid(row=1, column=1) 
    passw.grid(row=2, column=1) 
    Message.grid(row=4, column=1) 
    proceed.grid(row=5, column=1) 
    close.grid(row=5, column=0) 
#=====----LOG-IN WINDOW END----=====# 

#====----OPENING PAGE----=====# 
def destroyroot(): 
    root.destroy() 
LogInButton = Button(root, text="Log In", bg="#93ff00", command=newwindow).grid(row=1, column=0) 
CloseRoot = Button(root, text="Close window", bg="#93ff00", command=destroyroot).grid(row=3, column=0) 

root.mainloop() 
#===--OPENING PAGE END---====# 

#======================-------------END------------------======================# 
+3

Разбейте это на мелкие кусочки. Это не только побудит других людей помочь найти вашу ошибку, это, вероятно, приведет к тому, что вы сами найдете проблему.Вы также должны прочитать трассировку, потому что она, вероятно, сообщает вам, из какой строки возникает ошибка. – DanielSank

+0

Просто быстро справляясь с этим в редакторе, вы обнаружите ошибку на строке # 92, 'return f'. 'f' нигде не определяется. Однако я не думаю, что это вызывает вашу ошибку. Пожалуйста, разместите полную информацию о трассировке, так как будет легче диагностировать, где именно происходит ошибка. –

+0

К сожалению, да, я должен был удалить бит возврата, я просто играл с ним, чтобы увидеть, могу ли я удалить ошибку, используя это. Это трассировка, которую я получаю: «Исключение в обратном вызове Tkinter Traceback (последний последний звонок): Файл« E: \ Python \ lib \ lib-tk \ Tkinter.py », строка 1470, в __call__ return self .func (* args) Файл «путь к файлу», строка 14, в WriteFName file.write ("\ n") ТипError: дескриптор 'write' требует объекта 'file', но получил 'str'' – Callum

ответ

2

Вы неправильно настроили переменную file. Вы определяете его в функции newwindow, однако эта переменная не устанавливается в других функциях. Кроме того, file является типом в python (например, int, list и т. Д.). Поэтому вы НЕ должны использовать его как имя, откуда исходит ошибка. Вы делаете file.write, поэтому он получает write от типа, а не от переменной, и вы получаете посторонние ошибки.

+0

Хорошо , поэтому я изменил все «файл» на «f» за среднее время, вы могли бы предоставить и пример того, как я мог бы правильно установить переменную, используя что-то похожее на то, что у меня есть? Я просто пытаюсь представить себе, как это должно выглядеть, и я чувствую, что пример действительно поможет мне. Cheers. – Callum

+0

Вы должны передать его в качестве параметра для функций. Я не могу привести пример, так как ваш код довольно обширен, но если у вас проблемы с ним, я рекомендую играть с более простым кодом, прежде чем делать такие вещи. – Santiago

0

Некоторые основы Python для вас:

1) "от Tkinter импорта *" плохой форме. Это становится бесполезным, когда вы «импортируете» из нескольких модулей. Вместо этого попробуйте «импортировать Tkinter». Справочные методы как «Tkinter.xxxx». Например, «personal = Tkinter.Toplevel (root)».

2) «файл» - это тип в Python, поэтому вы никогда не должны использовать его как имя переменной. Использование «str» и «len» в качестве имен переменных - это другие распространенные ошибки для новых пользователей Python.

Продолжая, ваш код кажется очень сложным со всеми вложенными функциями.

Вы можете сделать лучше с классами, если у вас есть группы переменных, разделяемых различными функциями. Вот очень простой пример класса, который также показывает правильный путь для записи в файл:

class MyClass(object): 

    def __init__(self, file_name = r'c:\myfile.txt'): 
     self.file_name = file_name 

    def write_to_file(self, stuff_to_write): 
     with open(self.file_name, 'a') as f: 
      f.write(stuff_to_write) 

    def WriteLName(self, name): 
     text = "Last Name: %s\n"%name 
     self.write_to_file(text) 

output = MyClass(r'c:\output_file.txt') 
output.WriteLName('Jones') 

Делает файл с именем C: \ output_file.txt с текстом «Фамилия: Jones» в нем.

При определении переменной внутри функции, то она автоматически не «глобальный», так и другие функции не вижу:

def open_file(): 
    fout = open(r'c:\myfile.txt', 'w') 
def write_file(): 
    fout.write('some text\n') 

open_file() 
write_file() 

дает эту ошибку, когда вы попали в «fout.write» линии:

NameError: global name 'fout' is not defined 

Если вы добавляете глобальные объявления, оно работает так, как вы ожидаете. Многие скажут, что это «плохая форма», но в качестве быстрого исправления для вашего существующего кода это может быть что-то попробовать.

def open_file(): 
    global fout 
    fout = open(r'c:\myfile.txt', 'w') 
def write_file(): 
    global fout 
    fout.write('some text\n') 
open_file() 
write_file() 
+0

Приветствия за ответ, я отправляюсь спать сейчас, но я обязательно буду играть с вещами, о которых вы говорили завтра! – Callum

+0

В качестве дополнения к 1) вы можете использовать 'import Tkinter as tk', если вы не хотите каждый раз выписывать Tkinter. Таким образом вы можете использовать 'tk.xxx' вместо' Tkinter.xxx' – fhdrsdg

Смежные вопросы